From 3726ec767f970b16f40bf3b71f4a8adfb4ab6da4 Mon Sep 17 00:00:00 2001 From: Andrew Kane Date: Sun, 20 Apr 2025 21:52:11 -0700 Subject: [PATCH] Fix pointer class for closure arguments for FFI backend --- lib/fiddle/ffi_backend.rb | 6 ++++-- test/fiddle/test_closure.rb | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) 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