ffi 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of ffi might be problematic. Click here for more details.

Files changed (55) hide show
  1. data/README.rdoc +15 -15
  2. data/Rakefile +57 -8
  3. data/ext/ffi_c/AbstractMemory.c +101 -24
  4. data/ext/ffi_c/AbstractMemory.h +98 -6
  5. data/ext/ffi_c/ArrayType.c +129 -0
  6. data/ext/ffi_c/ArrayType.h +58 -0
  7. data/ext/ffi_c/AutoPointer.c +1 -0
  8. data/ext/ffi_c/Buffer.c +59 -43
  9. data/ext/ffi_c/Call.c +853 -0
  10. data/ext/ffi_c/Call.h +86 -0
  11. data/ext/ffi_c/ClosurePool.c +302 -0
  12. data/ext/ffi_c/ClosurePool.h +29 -0
  13. data/ext/ffi_c/DynamicLibrary.c +3 -0
  14. data/ext/ffi_c/Function.c +478 -0
  15. data/ext/ffi_c/Function.h +80 -0
  16. data/ext/ffi_c/FunctionInfo.c +221 -0
  17. data/ext/ffi_c/LastError.c +30 -6
  18. data/ext/ffi_c/MemoryPointer.c +50 -28
  19. data/ext/ffi_c/MethodHandle.c +346 -0
  20. data/ext/ffi_c/MethodHandle.h +53 -0
  21. data/ext/ffi_c/Pointer.c +73 -13
  22. data/ext/ffi_c/Pointer.h +31 -7
  23. data/ext/ffi_c/Struct.c +517 -224
  24. data/ext/ffi_c/Struct.h +60 -6
  25. data/ext/ffi_c/StructByValue.c +140 -0
  26. data/ext/ffi_c/StructByValue.h +53 -0
  27. data/ext/ffi_c/StructLayout.c +450 -0
  28. data/ext/ffi_c/Type.c +121 -22
  29. data/ext/ffi_c/Type.h +37 -8
  30. data/ext/ffi_c/Types.c +46 -61
  31. data/ext/ffi_c/Types.h +38 -7
  32. data/ext/ffi_c/Variadic.c +260 -0
  33. data/ext/ffi_c/compat.h +53 -3
  34. data/ext/ffi_c/extconf.rb +6 -7
  35. data/ext/ffi_c/ffi.c +45 -39
  36. data/ext/ffi_c/libffi.darwin.mk +2 -2
  37. data/ext/ffi_c/rbffi.h +3 -0
  38. data/lib/ffi/ffi.rb +7 -4
  39. data/lib/ffi/library.rb +34 -59
  40. data/lib/ffi/platform.rb +14 -4
  41. data/lib/ffi/struct.rb +110 -281
  42. data/lib/ffi/union.rb +4 -9
  43. data/lib/ffi/variadic.rb +1 -6
  44. data/spec/ffi/buffer_spec.rb +6 -0
  45. data/spec/ffi/callback_spec.rb +34 -3
  46. data/spec/ffi/function_spec.rb +73 -0
  47. data/spec/ffi/library_spec.rb +56 -52
  48. data/spec/ffi/pointer_spec.rb +3 -3
  49. data/spec/ffi/struct_callback_spec.rb +26 -3
  50. data/spec/ffi/struct_spec.rb +56 -3
  51. metadata +42 -11
  52. data/ext/ffi_c/Callback.c +0 -374
  53. data/ext/ffi_c/Callback.h +0 -47
  54. data/ext/ffi_c/Invoker.c +0 -962
  55. data/ext/ffi_c/NullPointer.c +0 -143
data/lib/ffi/union.rb CHANGED
@@ -1,17 +1,12 @@
1
1
  require 'ffi/struct'
2
2
 
3
3
  module FFI
4
- class UnionLayoutBuilder < FFI::StructLayoutBuilder
5
- private
6
- def calc_alignment_of(field_class, offset); 0; end
7
- def calc_current_size(offset, size)
8
- @size = size if size > @size
9
- end
10
- end
4
+
11
5
  class Union < FFI::Struct
12
- private
13
6
  def self.builder
14
- UnionLayoutBuilder.new
7
+ b = StructLayoutBuilder.new
8
+ b.union = true
9
+ b
15
10
  end
16
11
  end
17
12
  end
data/lib/ffi/variadic.rb CHANGED
@@ -1,10 +1,5 @@
1
1
  module FFI
2
- class VariadicInvoker
3
- def VariadicInvoker.new(function, arg_types, rb_ret_type, ret_type, options)
4
- invoker = self.__new(function, rb_ret_type, ret_type, options[:convention].to_s, options[:enums])
5
- invoker.init(arg_types, options[:type_map])
6
- invoker
7
- end
2
+ class VariadicInvoker
8
3
  def init(arg_types, type_map)
9
4
  @fixed = Array.new
10
5
  @type_map = type_map
@@ -194,3 +194,9 @@ describe "Buffer#put_pointer" do
194
194
  p2.get_uint(0).should == 0xdeadbeef
195
195
  end
196
196
  end
197
+ describe "Buffer#size" do
198
+ it "should return size" do
199
+ buf = FFI::Buffer.new 14
200
+ buf.size.should == 14
201
+ end
202
+ end
@@ -157,7 +157,7 @@ describe "Callback" do
157
157
  it "returning :uint (0xffffffff)" do
158
158
  LibTest.testCallbackVrU32 { 0xffffffff }.should == 0xffffffff
159
159
  end
160
- it "Callback returning :uint (-1)" do
160
+ it "returning :uint (-1)" do
161
161
  LibTest.testCallbackVrU32 { -1 }.should == 0xffffffff
162
162
  end
163
163
  it "returning :long (0)" do
@@ -233,6 +233,7 @@ describe "Callback" do
233
233
  it 'could be anonymous' do
234
234
  module LibTest
235
235
  extend FFI::Library
236
+ ffi_lib TestLibrary::PATH
236
237
  attach_function :testCallbackVrS8, :testClosureVrB, [ callback([ ], :char) ], :char
237
238
  end
238
239
  LibTest.testCallbackVrS8 { 0 }.should == 0
@@ -244,6 +245,7 @@ describe "Callback" do
244
245
  it "should not blow up when a callback is defined that returns a callback" do
245
246
  module LibTest
246
247
  extend FFI::Library
248
+ ffi_lib TestLibrary::PATH
247
249
  callback :cb_return_type_1, [ :short ], :short
248
250
  callback :cb_lookup_1, [ :short ], :cb_return_type_1
249
251
  attach_function :testReturnsCallback_1, :testReturnsClosure, [ :cb_lookup_1, :short ], :cb_return_type_1
@@ -253,6 +255,7 @@ describe "Callback" do
253
255
  it "should return a callback" do
254
256
  module LibTest
255
257
  extend FFI::Library
258
+ ffi_lib TestLibrary::PATH
256
259
  callback :cb_return_type, [ :int ], :int
257
260
  callback :cb_lookup, [ ], :cb_return_type
258
261
  attach_function :testReturnsCallback, :testReturnsClosure, [ :cb_lookup, :int ], :int
@@ -279,6 +282,7 @@ describe "Callback" do
279
282
  it "should return a method callback" do
280
283
  module LibTest
281
284
  extend FFI::Library
285
+ ffi_lib TestLibrary::PATH
282
286
  callback :cb_return_type, [ :int ], :int
283
287
  callback :cb_lookup, [ ], :cb_return_type
284
288
  attach_function :testReturnsCallback, :testReturnsClosure, [ :cb_lookup, :int ], :int
@@ -298,6 +302,7 @@ describe "Callback" do
298
302
  it 'should not blow up when a callback takes a callback as argument' do
299
303
  module LibTest
300
304
  extend FFI::Library
305
+ ffi_lib TestLibrary::PATH
301
306
  callback :cb_argument, [ :int ], :int
302
307
  callback :cb_with_cb_argument, [ :cb_argument, :int ], :int
303
308
  attach_function :testCallbackAsArgument, :testArgumentClosure, [ :cb_with_cb_argument, :int ], :int
@@ -306,6 +311,7 @@ describe "Callback" do
306
311
  it 'should be able to use the callback argument' do
307
312
  module LibTest
308
313
  extend FFI::Library
314
+ ffi_lib TestLibrary::PATH
309
315
  callback :cb_argument, [ :int ], :int
310
316
  callback :cb_with_cb_argument, [ :cb_argument, :int ], :int
311
317
  attach_function :testCallbackAsArgument, :testArgumentClosure, [ :cb_with_cb_argument, :cb_argument, :int ], :int
@@ -328,6 +334,7 @@ describe "Callback" do
328
334
  it 'function returns callable object' do
329
335
  module LibTest
330
336
  extend FFI::Library
337
+ ffi_lib TestLibrary::PATH
331
338
  callback :funcptr, [ :int ], :int
332
339
  attach_function :testReturnsFunctionPointer, [ ], :funcptr
333
340
  end
@@ -337,7 +344,7 @@ describe "Callback" do
337
344
  end
338
345
 
339
346
  end
340
- describe "primitive argument" do
347
+ describe "Callback with " do
341
348
  #
342
349
  # Test callbacks that take an argument, returning void
343
350
  #
@@ -355,6 +362,8 @@ describe "primitive argument" do
355
362
 
356
363
  callback :cbLrV, [ :long ], :void
357
364
  callback :cbULrV, [ :ulong ], :void
365
+ callback :cbArV, [ :string ], :void
366
+ callback :cbPrV, [ :pointer], :void
358
367
 
359
368
  callback :cbS64rV, [ :long_long ], :void
360
369
  attach_function :testCallbackCrV, :testClosureBrV, [ :cbS8rV, :char ], :void
@@ -369,6 +378,8 @@ describe "primitive argument" do
369
378
  attach_function :testCallbackULrV, :testClosureULrV, [ :cbULrV, :ulong ], :void
370
379
 
371
380
  attach_function :testCallbackLLrV, :testClosureLLrV, [ :cbS64rV, :long_long ], :void
381
+ attach_function :testCallbackArV, :testClosurePrV, [ :cbArV, :string ], :void
382
+ attach_function :testCallbackPrV, :testClosurePrV, [ :cbPrV, :pointer], :void
372
383
  end
373
384
  it ":char (0) argument" do
374
385
  v = 0xdeadbeef
@@ -556,5 +567,25 @@ describe "primitive argument" do
556
567
  LibTest.testCallbackLLrV(-1) { |i| v = i }
557
568
  v.should == -1
558
569
  end
559
-
570
+ it ":string argument" do
571
+ v = nil
572
+ LibTest.testCallbackArV("Hello, World") { |i| v = i }
573
+ v.should == "Hello, World"
574
+ end
575
+ it ":string (nil) argument" do
576
+ v = "Hello, World"
577
+ LibTest.testCallbackArV(nil) { |i| v = i }
578
+ v.should be_nil
579
+ end
580
+ it ":pointer argument" do
581
+ v = nil
582
+ magic = FFI::Pointer.new(0xdeadbeef)
583
+ LibTest.testCallbackPrV(magic) { |i| v = i }
584
+ v.should == magic
585
+ end
586
+ it ":pointer (nil) argument" do
587
+ v = "Hello, World"
588
+ LibTest.testCallbackPrV(nil) { |i| v = i }
589
+ v.should == FFI::Pointer::NULL
590
+ end
560
591
  end # unless true
@@ -0,0 +1,73 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
2
+
3
+ describe FFI::Function do
4
+ before do
5
+ module LibTest
6
+ extend FFI::Library
7
+ ffi_lib TestLibrary::PATH
8
+ attach_function :testFunctionAdd, [:int, :int, :pointer], :int
9
+ end
10
+ @libtest = FFI::DynamicLibrary.open(TestLibrary::PATH,
11
+ FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_GLOBAL)
12
+ end
13
+ it 'is initialized with a signature and a block' do
14
+ FFI::Function.new(:int, []) { }
15
+ end
16
+ it 'raises an error when passing a wrong signature' do
17
+ lambda { FFI::Function.new([], :int).new { } }.should raise_error TypeError
18
+ end
19
+ it 'returns a native pointer' do
20
+ FFI::Function.new(:int, []) { }.kind_of? FFI::Pointer
21
+ end
22
+ it 'can be used as callback from C passing to it a block' do
23
+ function_add = FFI::Function.new(:int, [:int, :int]) { |a, b| a + b }
24
+ LibTest.testFunctionAdd(10, 10, function_add).should == 20
25
+ end
26
+ it 'can be used as callback from C passing to it a Proc object' do
27
+ function_add = FFI::Function.new(:int, [:int, :int], Proc.new { |a, b| a + b })
28
+ LibTest.testFunctionAdd(10, 10, function_add).should == 20
29
+ end
30
+ it 'can be used to wrap an existing function pointer' do
31
+ FFI::Function.new(:int, [:int, :int], @libtest.find_function('testAdd')).call(10, 10).should == 20
32
+ end
33
+ it 'can be attached to a module' do
34
+ module Foo; end
35
+ fp = FFI::Function.new(:int, [:int, :int], @libtest.find_function('testAdd'))
36
+ fp.attach(Foo, 'add')
37
+ Foo.add(10, 10).should == 20
38
+ end
39
+ it 'can be used to extend an object' do
40
+ fp = FFI::Function.new(:int, [:int, :int], @libtest.find_function('testAdd'))
41
+ foo = Object.new
42
+ class << foo
43
+ def singleton_class
44
+ class << self; self; end
45
+ end
46
+ end
47
+ fp.attach(foo.singleton_class, 'add')
48
+ foo.add(10, 10).should == 20
49
+ end
50
+ it 'can wrap a blocking function' do
51
+ unless RUBY_VERSION =~ /1.8/
52
+ fp = FFI::Function.new(:void, [ :int ], @libtest.find_function('testBlocking'), :blocking => true)
53
+ time = Time.now
54
+ threads = []
55
+ threads << Thread.new { fp.call(2) }
56
+ threads << Thread.new(time) { (Time.now - time).should < 1 }
57
+ threads.each { |t| t.join }
58
+ end
59
+ end
60
+ it 'autorelease flag is set to true by default' do
61
+ fp = FFI::Function.new(:int, [:int, :int], @libtest.find_function('testAdd'))
62
+ fp.autorelease?.should be_true
63
+ end
64
+ it 'can explicity free itself' do
65
+ fp = FFI::Function.new(:int, []) { }
66
+ fp.free
67
+ lambda { fp.free }.should raise_error RuntimeError
68
+ end
69
+ it 'can\'t explicity free itself if not previously allocated' do
70
+ fp = FFI::Function.new(:int, [:int, :int], @libtest.find_function('testAdd'))
71
+ lambda { fp.free }.should raise_error RuntimeError
72
+ end
73
+ end
@@ -1,57 +1,61 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
2
2
  describe "Library" do
3
- it "attach_function with no library specified" do
4
- lambda {
5
- Module.new do |m|
6
- m.extend FFI::Library
7
- attach_function :getpid, [ ], :uint
8
- end
9
- }.should_not raise_error
10
- end
11
- it "attach_function :getpid from this process" do
12
- lambda {
13
- Module.new do |m|
14
- m.extend FFI::Library
15
- attach_function :getpid, [ ], :uint
16
- end.getpid.should == Process.pid
17
- }.should_not raise_error
18
- end
19
- it "attach_function :getpid from [ 'c', 'libc.so.6'] " do
20
- lambda {
21
- Module.new do |m|
22
- m.extend FFI::Library
23
- ffi_lib 'c', 'libc.so.6'
24
- attach_function :getpid, [ ], :uint
25
- end.getpid.should == Process.pid
26
- }.should_not raise_error
27
- end
28
- it "attach_function :getpid from [ 'libc.so.6', 'c' ] " do
29
- lambda {
30
- Module.new do |m|
31
- m.extend FFI::Library
32
- ffi_lib 'libc.so.6', 'c'
33
- attach_function :getpid, [ ], :uint
34
- end.getpid.should == Process.pid
35
- }.should_not raise_error
36
- end
37
- it "attach_function :getpid from [ 'libfubar.so.0xdeadbeef', nil, 'c' ] " do
38
- lambda {
39
- Module.new do |m|
40
- m.extend FFI::Library
41
- ffi_lib 'libfubar.so.0xdeadbeef', nil, 'c'
42
- attach_function :getpid, [ ], :uint
43
- end.getpid.should == Process.pid
44
- }.should_not raise_error
45
- end
46
- it "attach_function :getpid from [ 'libfubar.so.0xdeadbeef' ] " do
47
- lambda {
48
- Module.new do |m|
49
- m.extend FFI::Library
50
- ffi_lib 'libfubar.so.0xdeadbeef'
51
- attach_function :getpid, [ ], :uint
52
- end.getpid.should == Process.pid
53
- }.should raise_error(LoadError)
3
+
4
+ unless Config::CONFIG['target_os'] =~ /mingw/ || Config::CONFIG['target_os'] =~ /win/
5
+ it "attach_function with no library specified" do
6
+ lambda {
7
+ Module.new do |m|
8
+ m.extend FFI::Library
9
+ attach_function :getpid, [ ], :uint
10
+ end
11
+ }.should_not raise_error
12
+ end
13
+ it "attach_function :getpid from this process" do
14
+ lambda {
15
+ Module.new do |m|
16
+ m.extend FFI::Library
17
+ attach_function :getpid, [ ], :uint
18
+ end.getpid.should == Process.pid
19
+ }.should_not raise_error
20
+ end
21
+ it "attach_function :getpid from [ 'c', 'libc.so.6'] " do
22
+ lambda {
23
+ Module.new do |m|
24
+ m.extend FFI::Library
25
+ ffi_lib 'c', 'libc.so.6'
26
+ attach_function :getpid, [ ], :uint
27
+ end.getpid.should == Process.pid
28
+ }.should_not raise_error
29
+ end
30
+ it "attach_function :getpid from [ 'libc.so.6', 'c' ] " do
31
+ lambda {
32
+ Module.new do |m|
33
+ m.extend FFI::Library
34
+ ffi_lib 'libc.so.6', 'c'
35
+ attach_function :getpid, [ ], :uint
36
+ end.getpid.should == Process.pid
37
+ }.should_not raise_error
38
+ end
39
+ it "attach_function :getpid from [ 'libfubar.so.0xdeadbeef', nil, 'c' ] " do
40
+ lambda {
41
+ Module.new do |m|
42
+ m.extend FFI::Library
43
+ ffi_lib 'libfubar.so.0xdeadbeef', nil, 'c'
44
+ attach_function :getpid, [ ], :uint
45
+ end.getpid.should == Process.pid
46
+ }.should_not raise_error
47
+ end
48
+ it "attach_function :getpid from [ 'libfubar.so.0xdeadbeef' ] " do
49
+ lambda {
50
+ Module.new do |m|
51
+ m.extend FFI::Library
52
+ ffi_lib 'libfubar.so.0xdeadbeef'
53
+ attach_function :getpid, [ ], :uint
54
+ end.getpid.should == Process.pid
55
+ }.should raise_error(LoadError)
56
+ end
54
57
  end
58
+
55
59
  def gvar_lib(name, type)
56
60
  Module.new do |m|
57
61
  m.extend FFI::Library
@@ -141,4 +145,4 @@ describe "Library" do
141
145
  lib.gvar = val
142
146
  lib.get.should == val
143
147
  end
144
- end
148
+ end
@@ -182,13 +182,13 @@ describe "AutoPointer#new" do
182
182
  class AutoPointerSubclass < FFI::AutoPointer
183
183
  def self.release(ptr); end
184
184
  end
185
- it "MemoryPointer argument raises ArgumentError" do
185
+ it "MemoryPointer argument raises TypeError" do
186
186
  lambda { FFI::AutoPointer.new(FFI::MemoryPointer.new(:int))}.should raise_error(::TypeError)
187
187
  end
188
- it "AutoPointer argument raises ArgumentError" do
188
+ it "AutoPointer argument raises TypeError" do
189
189
  lambda { AutoPointerSubclass.new(AutoPointerSubclass.new(LibTest.ptr_from_address(0))) }.should raise_error(::TypeError)
190
190
  end
191
- it "Buffer argument raises ArgumentError" do
191
+ it "Buffer argument raises TypeError" do
192
192
  lambda { FFI::AutoPointer.new(FFI::Buffer.new(:int))}.should raise_error(::TypeError)
193
193
  end
194
194
 
@@ -5,11 +5,13 @@ describe FFI::Struct, ' with inline callback functions' do
5
5
  module CallbackMember
6
6
  extend FFI::Library
7
7
  ffi_lib TestLibrary::PATH
8
+ DUMMY_CB = callback :dummy_cb, [ :int ], :int
8
9
  class TestStruct < FFI::Struct
9
10
  layout \
10
11
  :add, callback([ :int, :int ], :int),
11
- :sub, callback([ :int, :int ], :int)
12
- end
12
+ :sub, callback([ :int, :int ], :int),
13
+ :cb_with_cb_parameter, callback([ DUMMY_CB, :int ], :int)
14
+ end
13
15
  attach_function :struct_call_add_cb, [TestStruct, :int, :int], :int
14
16
  attach_function :struct_call_sub_cb, [TestStruct, :int, :int], :int
15
17
  end
@@ -22,7 +24,7 @@ describe FFI::Struct, ' with inline callback functions' do
22
24
  layout \
23
25
  :add, callback([ :int, :int ], :int),
24
26
  :sub, callback([ :int, :int ], :int)
25
- end
27
+ end
26
28
  attach_function :struct_call_add_cb, [TestStruct, :int, :int], :int
27
29
  attach_function :struct_call_sub_cb, [TestStruct, :int, :int], :int
28
30
  end
@@ -37,5 +39,26 @@ describe FFI::Struct, ' with inline callback functions' do
37
39
 
38
40
  CallbackMember.struct_call_add_cb(ts, 1, 2).should == 3
39
41
  end
42
+
43
+ it 'should return callable object from []' do
44
+ module CallbackMember
45
+ extend FFI::Library
46
+ ffi_lib TestLibrary::PATH
47
+ class TestStruct < FFI::Struct
48
+ layout \
49
+ :add, callback([ :int, :int ], :int),
50
+ :sub, callback([ :int, :int ], :int)
51
+ end
52
+ attach_function :struct_call_add_cb, [TestStruct, :int, :int], :int
53
+ attach_function :struct_call_sub_cb, [TestStruct, :int, :int], :int
54
+ end
55
+
56
+ s = CallbackMember::TestStruct.new
57
+ add = Proc.new { |a,b| a+b}
58
+ s[:add] = add
59
+ fn = s[:add]
60
+ fn.respond_to?(:call).should be_true
61
+ fn.call(1, 2).should == 3
62
+ end
40
63
  end
41
64
 
@@ -379,6 +379,59 @@ describe FFI::Struct, ' with a nested struct field' do
379
379
  end
380
380
  end
381
381
 
382
+ describe FFI::Struct, ' by value' do
383
+ module LibTest
384
+ extend FFI::Library
385
+ ffi_lib TestLibrary::PATH
386
+
387
+ class S8S32 < FFI::Struct
388
+ layout :s8, :char, :s32, :int
389
+ end
390
+ attach_function :struct_return_s8s32, [ ], S8S32.by_value
391
+ attach_function :struct_s8s32_set, [ :char, :int ], S8S32.by_value
392
+ attach_function :struct_s8s32_get_s8, [ S8S32.by_value ], :char
393
+ attach_function :struct_s8s32_get_s32, [ S8S32.by_value ], :int
394
+ attach_function :struct_s8s32_s32_ret_s32, [ S8S32.by_value, :int ], :int
395
+ attach_function :struct_s8s32_s64_ret_s64, [ S8S32.by_value, :long_long ], :long_long
396
+ end
397
+
398
+ it 'return using pre-set values' do
399
+ s = LibTest.struct_return_s8s32
400
+ s[:s8].should == 0x7f
401
+ s[:s32].should == 0x12345678
402
+ end
403
+
404
+ it 'return using passed in values' do
405
+ s = LibTest.struct_s8s32_set(123, 456789)
406
+ s[:s8].should == 123
407
+ s[:s32].should == 456789
408
+ end
409
+
410
+ it 'parameter' do
411
+ s = LibTest::S8S32.new
412
+ s[:s8] = 0x12
413
+ s[:s32] = 0x34567890
414
+ LibTest.struct_s8s32_get_s8(s).should == 0x12
415
+ LibTest.struct_s8s32_get_s32(s).should == 0x34567890
416
+ end
417
+
418
+ it 'parameter with following s32' do
419
+ s = LibTest::S8S32.new
420
+ s[:s8] = 0x12
421
+ s[:s32] = 0x34567890
422
+
423
+ LibTest.struct_s8s32_s32_ret_s32(s, 0x1eefdead).should == 0x1eefdead
424
+ end
425
+
426
+ it 'parameter with following s64' do
427
+ s = LibTest::S8S32.new
428
+ s[:s8] = 0x12
429
+ s[:s32] = 0x34567890
430
+
431
+ LibTest.struct_s8s32_s64_ret_s64(s, 0xdeadcafebabe).should == 0xdeadcafebabe
432
+ end
433
+ end
434
+
382
435
  describe FFI::Struct, ' with an array field' do
383
436
  module LibTest
384
437
  extend FFI::Library
@@ -399,9 +452,9 @@ describe FFI::Struct, ' with an array field' do
399
452
  @s = LibTest::StructWithArray.new(LibTest.struct_make_struct_with_array(0, 1, 2, 3, 4))
400
453
  @s[:a].to_a.should == [0, 1, 2, 3, 4]
401
454
  end
402
- it 'should cache array object for successive calls' do
403
- @s[:a].object_id.should == @s[:a].object_id
404
- end
455
+ # it 'should cache array object for successive calls' do
456
+ # @s[:a].object_id.should == @s[:a].object_id
457
+ # end
405
458
  it 'should return the size of the array field in bytes' do
406
459
  @s = LibTest::StructWithArray.new(LibTest.struct_make_struct_with_array(0, 1, 2, 3, 4))
407
460
  @s[:a].size.should == 20