Subject:
[ruby-ffi] Re: Initialize FFI::Pointer in C?
From:
Simon Chiang
Date:
12/9/09 6:27 PM
To:
ruby-ffi

I thought I had tried that but I was wrong... works great!  Thank you
very much.

On Dec 9, 1:29 pm, Wayne Meissner <wmeiss...@gmail.com> wrote:
> You can setup that callback all from ruby.
>
> module Foo
>   callback :my_callback, [ :pointer ], :int
>   attach_function :DefineFunction, [ :string, :char, :my_callback, :string ]
> end
>
> Then you set it up like so:
>
> cb = Proc.new do |p|
>    # Do whatever you want to do in the callback here
>    puts "pointer=#{p.inspect}"
>    # return zero to C code
>    0
> end
>
> Foo.DefineFunction("ruby-callback, "d".ord, cb, "RubyCallback")
>
> You need to stash the 'cb' reference somewhere so it does not get
> garbage collected until the callback is no longer needed, but that is
> all the setup you should need to do to use that api from FFI.
>
> 2009/12/10 Simon Chiang <simon.a.chi...@gmail.com>:
>
> > The problem is that I need to register the C function with a codebase
> > I don't control.  I need to call a function like this in C:
>
> >  int RubyCallback(void *thing) {...}
>
> >  DefineFunction("ruby-callback", 'd', (int (*)(void)) RubyCallback,
> > "RubyCallback");
>
> > The leading inputs are not important for the example but if you look
> > at the latter arguments you can see I need both a pointer to the
> > callback function and the name of the function.  I think the FFI
> > callback provides a function pointer but not a name, right?  Is there
> > a way I can name the callback?
>
> > I'm ok with manually maintaining my calls to the C api.  Do you have
> > suggestions about how I can use it in this context? Thanks.
>
> > ==== FYI
>
> > This is the signature of the DefineFunction method.
>
> >  int      DefineFunction(functionName,functionType,
> > functionPointer,actualFunctionName);
> >  char    *functionName, functionType, *actualFunctionName;
> >  int    (*functionPointer)();
>
> > And if it helps, the version of the passing OS X is 10.5.8.
>
> > On Dec 9, 12:04 am, Wayne Meissner <wmeiss...@gmail.com> wrote:
> >> Really, don't use the C api - it will break at some point, since it is
> >> not intended in any way to be a public api.
>
> >> Use a FFI callback to call from C to ruby.
>
> >>http://wiki.github.com/ffi/ffi/exampleshasa callback example, as
> >> doeshttp://wiki.github.com/ffi/ffi/windows-examples
>
> >> 2009/12/9 Simon Chiang <simon.a.chi...@gmail.com>:
>
> >> > I'm building a callback to ruby from an extension and I would like to
> >> > pass back pointers much like an attached function that returns
> >> > a :pointer.  Basically something like this:
>
> >> >  int RubyCallback(void *thing)
> >> >  {
> >> >    VALUE ffi_pointer = rbffi_Pointer_NewInstance(thing);
> >> >    VALUE ruby_module = rb_const_get(rb_cObject, rb_intern
> >> > ("SomeModule"));
> >> >    VALUE ruby_result = rb_funcall(ruby_module, rb_intern("callback"),
> >> > 1, ffi_pointer);
>
> >> >    long result = FIX2INT(ruby_result);
> >> >    return(result);
> >> >  }
>
> >> > And then in ruby:
>
> >> >  module SomeModule
> >> >    module_function
>
> >> >    def callback(ptr)
> >> >       ptr.inspect         # => shows this to be an FFI::Pointer
> >> >    end
> >> >  end
>
> >> > A method like this works on OS X with ffi-0.5.0 (pre snow-lepoard,
> >> > I'll get the version if necessary) but results in a segfault on snow
> >> > leopard 10.6.2.  The segfault is triggered upon inspect.  I don't know
> >> > how FFI works... I really only got this working by taking a guess at
> >> > what rbffi_Pointer_NewInstance does.  Any ideas what's going wrong on
> >> > 10.6.2 and/or how I can do this better?
>
>