Subject:
Re: [ruby-ffi] Re: Initialize FFI::Pointer in C?
From:
Wayne Meissner
Date:
12/9/09 2:29 PM
To:
ruby-ffi@googlegroups.com

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.chiang@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/exampleshas a 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?
>>
>>
>