New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Calling a native function through a function pointer #404
Comments
Are you looking to call that yourself or for the C library to call it? Regardless of the use case there the underlying class for both the callbacks and functions is a pointer class. Take a look at Callbacks and the struct callback spec. All of those should respond to #call. Here's the relevant spec: module CallbackMember3
extend FFI::Library
ffi_lib TestLibrary::PATH
class TestStruct < FFI::Struct
layout \
:add, callback([ :int, :int ], :int),
:sub, callback([ :int, :int ], :int)
end
attach_function :struct_call_add_cb, [TestStruct, :int, :int], :int
attach_function :struct_call_sub_cb, [TestStruct, :int, :int], :int
end
s = CallbackMember3::TestStruct.new
add = Proc.new { |a,b| a+b}
s[:add] = add
fn = s[:add]
expect(fn.respond_to?(:call)).to be true
expect(fn.call(1, 2)).to eq(3) The documentation for most of ffi needs a pretty good review. |
I need to call it from my code. The library appears to be using structures full of pointers to approximate virtual functions, but using only C. Calling various factory methods yields said structures, and I need to call the provided "virtual methods" from Ruby. Using your example, I think I need something like... attach_function :factory_method, [], TestStruct
subclass = CallbackMember3.factory_method()
fn = subclass[:add]
fn.call(3,4) # => call whatever method the pointer points to |
That looks about right. There should be no need to park the function in a variable: |
That did the trick, thanks. The only remaining hangup came from using nested structures, which meant that I needed to use #ptr to reference the nested one... class FunctionTable < FFI::Struct
layout :function1, callback(...)
end
class MyStruct < FFI::Struct
layout :vt, FunctionTable.ptr # <= This is the part that I forgot
end
my_struct = factory_method()
my_struct[:vt][:function1].call(...) # It works! Thanks for your help. Is there a good place to add this to the documentation? I might as well make sure that no one else gets hung up on this. |
I'd add it to the wiki. Possibly, to the |
Done and done. |
Thanks! |
I'm working with an existing library that has methods that return pointers to structures full of pointers to functions. Using the documentation (thanks!) I've figured out how to model the pointers in the structures, but to do anything useful with the structures I need to be able to call the pointed-to-functions. So far, I haven't found the magic incantation in the docs, and my Google-fu is failing me.
I'm getting structs of the form...
How do I call
func1
,func2
, etc?If calling function pointers isn't already implemented, I'd be willing to take a stab at it if someone would be kind enough to point me in the right direction.
The text was updated successfully, but these errors were encountered: