From: Daniel Berger Date: 2010-01-13T08:00:42+09:00 Subject: Re: ffi, kerberos On Jan 12, 3:48 pm, Daniel Berger wrote: > Hi, > > I'm trying to wrap two function calls from kerberos, krb5_init_context > and krb5_free_context. Here are the prototypes for both: > > krb5_init_context(krb5_context * context) => krb5_error_code > krb5_free_context(krb5_context context) => void > > krb5_context is a struct, but unfortunately I don't know what its > members are. > > From the docs: > >      The krb5_context structure is designed to hold all per thread > state. All >      global variables that are context specific are stored in this > structure, >      including default encryption types, credentials-cache (ticket > file), and >      default realms. > >      The internals of the structure should never be accessed directly, > func- >      tions exist for extracting information. > > All I know is that it's 8 bytes in size. > > I tried something like this, but it didn't work: > > require 'ffi' > > module Krb5 >   class Context >     extend FFI::Library > >     class Error < StandardError; end > >     ffi_lib 'krb5' > >     attach_function :krb5_init_context, [:string], :uint >     attach_function :krb5_free_context, [:string], :void > >     def initialize >       @ctx = FFI::MemoryPointer.new(:pointer, 8) >       ret = krb5_init_context(@ctx) > >       if ret > 0 >         raise Error, "krb5_init_context() failed" >       end > >       if block_given? >         begin >           yield self >         ensure >           free >         end >       end >     end > >     def free >       krb5_free_context(@ctx) >     end >   end > end > > k = Krb5::Context.new > k.free > > I can use a plain string buffer, but then it segfaults on the 'free' > call. > > Any suggestions? Oops, here's an updated version, but it segfaults on the 'free' call: require 'ffi' module Krb5 class Context extend FFI::Library class Error < StandardError; end ffi_lib 'krb5' attach_function :krb5_init_context, [:pointer], :uint attach_function :krb5_free_context, [:pointer], :void def initialize @ctx = FFI::MemoryPointer.new(:char, 8) ret = krb5_init_context(@ctx) if ret > 0 raise Error, "krb5_init_context() failed" end if block_given? begin yield self ensure free end end end def free krb5_free_context(@ctx) end end end k = Krb5::Context.new k.free