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.
<wmeiss...@gmail.com> wrote:On Dec 9, 12:04 am, Wayne MeissnerReally, 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
<simon.a.chi...@gmail.com>:2009/12/9 Simon Chiang
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?