From: Daniel Berger Date: 2010-01-14T06:56:56+09:00 Subject: Re: ffi, kerberos Luc Heinrich wrote: > On 13 janv. 2010, at 16:53, Daniel Berger wrote: > > > Now I need to figure out how to create an FFI::MemoryPointer without > > necessarily knowing the size of the first argument. > > The one bit you are missing here is that krb5_context is not a struct. It's a *pointer* to a struct as can be seen in krb5/krb5.h: > > typedef struct _krb5_context * krb5_context; > > If krb5_context was a struct you wouldn't be able to do this in C: > > krb5_context ctx; > krb5_init_context(&ctx); > > Because event the C compiler would not know how to statically allocate without knowing the size of the struct. I assure you that it would complain :) > > So, with that in mind you can now simply completely ignore the size of the struct and only use pointers. Like this: > > module FFI::Krb5 > extend FFI::Library > ffi_lib "krb5" > > attach_function :krb5_init_context, [:buffer_out], :uint > attach_function :krb5_free_context, [:pointer], :void > end > > What you pass to krb5_init_context is really a pointer to a pointer. You can now use that this way: > > buf = FFI::Buffer.new(:pointer) > res = FFI::Krb5.krb5_init_context(buf) > puts res > > First you allocate a buffer which will contain a pointer (the krb5_context, which is, you get it now, a pointer :)), and then you pass this buffer to the krb5_init_context. But now you will probably want to *use* this context so you first have to get it out of the buffer, like this: > > ctx = buf.get_pointer(0) > > Which allows you to use it in any other krb5_* call, like the krb5_free_context which we have defined: > > FFI::Krb5.krb5_free_context(ptr) Thank you. This was very helpful. Regards, Dan