diff --git a/lib/fiddle/ffi_backend.rb b/lib/fiddle/ffi_backend.rb index eac469af..040535d5 100644 --- a/lib/fiddle/ffi_backend.rb +++ b/lib/fiddle/ffi_backend.rb @@ -159,15 +159,16 @@ def call(*args, &block) args[i] = Fiddle::FFIBackend.to_ffi_type(args[i]) end else - args.map! do |arg| - if arg.respond_to?(:to_ptr) - begin - arg = arg.to_ptr - end until arg.is_a?(FFI::Pointer) || !arg.respond_to?(:to_ptr) - arg - else - arg - end + @args.each_with_index do |arg_type, i| + next unless arg_type == Types::VOIDP + + src = args[i] + next if src.nil? + next if src.is_a?(String) + next if src.is_a?(FFI::AbstractMemory) + next if src.is_a?(FFI::Struct) + + args[i] = Pointer[src] end end result = @function.call(*args, &block) @@ -308,6 +309,8 @@ def initialize(addr, size = nil, free = nil) end elsif addr.is_a?(IO) raise NotImplementedError, "IO ptr isn't supported" + else + FFI::Pointer.new(Integer(addr)) end @size = size ? size : ptr.size diff --git a/test/fiddle/test_function.rb b/test/fiddle/test_function.rb index 146dcc72..b408a14c 100644 --- a/test/fiddle/test_function.rb +++ b/test/fiddle/test_function.rb @@ -98,6 +98,15 @@ def test_call assert_in_delta 1.0, func.call(90 * Math::PI / 180), 0.0001 end + def test_integer_pointer_conversion + func = Function.new(@libc['memcpy'], [TYPE_VOIDP, TYPE_VOIDP, TYPE_SIZE_T], TYPE_VOIDP) + str = 'hello' + Pointer.malloc(str.bytesize, Fiddle::RUBY_FREE) do |dst| + func.call(dst.to_i, str, dst.size) + assert_equal(str, dst.to_str) + end + end + def test_argument_count closure_class = Class.new(Closure) do def call one diff --git a/test/fiddle/test_pointer.rb b/test/fiddle/test_pointer.rb index d46fb662..4afc3f89 100644 --- a/test/fiddle/test_pointer.rb +++ b/test/fiddle/test_pointer.rb @@ -161,11 +161,17 @@ def test_to_ptr_with_ptr end end - def test_to_ptr_with_num + def test_to_ptr_with_int ptr = Pointer.new 0 assert_equal ptr, Pointer[0] end + MimicInteger = Struct.new(:to_int) + def test_to_ptr_with_to_int + ptr = Pointer.new 0 + assert_equal ptr, Pointer[MimicInteger.new(0)] + end + def test_equals ptr = Pointer.new 0 ptr2 = Pointer.new 0