diff --git a/lib/fiddle/ffi_backend.rb b/lib/fiddle/ffi_backend.rb index e564ce89..0c385510 100644 --- a/lib/fiddle/ffi_backend.rb +++ b/lib/fiddle/ffi_backend.rb @@ -188,8 +188,10 @@ def initialize(ret, args, abi = Function::DEFAULT) end return_type = Fiddle::FFIBackend.to_ffi_type(@ctype) raise "#{self.class} must implement #call" unless respond_to?(:call) - callable = method(:call) - @function = FFI::Function.new(return_type, ffi_args, callable, convention: abi) + wrapper = lambda do |*args| + call(*args.map { |v| v.is_a?(FFI::Pointer) ? Pointer.new(v) : v }) + end + @function = FFI::Function.new(return_type, ffi_args, wrapper, convention: abi) @freed = false end diff --git a/test/fiddle/test_closure.rb b/test/fiddle/test_closure.rb index 26cff8e5..ee9ef044 100644 --- a/test/fiddle/test_closure.rb +++ b/test/fiddle/test_closure.rb @@ -87,6 +87,20 @@ def call(bool) end end + def test_pointer + closure_class = Class.new(Closure) do + def call(ptr) + ptr.is_a?(Pointer) + end + end + closure_class.create(:bool, [:voidp]) do |closure| + func = Function.new(closure, [:voidp], :bool) + assert do + func.call(Pointer["hello"]) + end + end + end + def test_free closure_class = Class.new(Closure) do def call