Skip to content

Commit e2f0952

Browse files
ffi_backend: convert numeric function args to pointers (#162)
This allows for passing integers as pointer arguments to functions when using the FFI backend. This is a workaround until we can get JRuby's FFI implementation to allow for it directly (see also jruby/jruby#8423) --------- Co-authored-by: Benoit Daloze <eregontp@gmail.com>
1 parent 77d3dc9 commit e2f0952

3 files changed

Lines changed: 28 additions & 10 deletions

File tree

‎lib/fiddle/ffi_backend.rb‎

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -159,15 +159,16 @@ def call(*args, &block)
159159
args[i]=Fiddle::FFIBackend.to_ffi_type(args[i])
160160
end
161161
else
162-
args.map!do |arg|
163-
ifarg.respond_to?(:to_ptr)
164-
begin
165-
arg=arg.to_ptr
166-
enduntilarg.is_a?(FFI::Pointer) || !arg.respond_to?(:to_ptr)
167-
arg
168-
else
169-
arg
170-
end
162+
@args.each_with_indexdo |arg_type,i|
163+
nextunlessarg_type == Types::VOIDP
164+
165+
src=args[i]
166+
nextifsrc.nil?
167+
nextifsrc.is_a?(String)
168+
nextifsrc.is_a?(FFI::AbstractMemory)
169+
nextifsrc.is_a?(FFI::Struct)
170+
171+
args[i]=Pointer[src]
171172
end
172173
end
173174
result=@function.call(*args, &block)
@@ -316,6 +317,8 @@ def initialize(addr, size = nil, free = nil)
316317
end
317318
elsifaddr.is_a?(IO)
318319
raiseNotImplementedError,"IO ptr isn't supported"
320+
else
321+
FFI::Pointer.new(Integer(addr))
319322
end
320323

321324
@size=size ? size : ptr.size

‎test/fiddle/test_function.rb‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,15 @@ def test_call
9898
assert_in_delta1.0,func.call(90 * Math::PI / 180),0.0001
9999
end
100100

101+
deftest_integer_pointer_conversion
102+
func=Function.new(@libc['memcpy'],[TYPE_VOIDP,TYPE_VOIDP,TYPE_SIZE_T],TYPE_VOIDP)
103+
str='hello'
104+
Pointer.malloc(str.bytesize,Fiddle::RUBY_FREE)do |dst|
105+
func.call(dst.to_i,str,dst.size)
106+
assert_equal(str,dst.to_str)
107+
end
108+
end
109+
101110
deftest_argument_count
102111
closure_class=Class.new(Closure)do
103112
defcallone

‎test/fiddle/test_pointer.rb‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,11 +157,17 @@ def test_to_ptr_with_ptr
157157
end
158158
end
159159

160-
deftest_to_ptr_with_num
160+
deftest_to_ptr_with_int
161161
ptr=Pointer.new0
162162
assert_equalptr,Pointer[0]
163163
end
164164

165+
MimicInteger=Struct.new(:to_int)
166+
deftest_to_ptr_with_to_int
167+
ptr=Pointer.new0
168+
assert_equalptr,Pointer[MimicInteger.new(0)]
169+
end
170+
165171
deftest_equals
166172
ptr=Pointer.new0
167173
ptr2=Pointer.new0

0 commit comments

Comments
 (0)