ffi 1.9.3 → 1.9.5
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.
- checksums.yaml +6 -14
- data/Rakefile +12 -15
- data/ext/ffi_c/DynamicLibrary.c +9 -5
- data/ext/ffi_c/DynamicLibrary.h +49 -0
- data/ext/ffi_c/Function.c +4 -3
- data/ext/ffi_c/FunctionInfo.c +2 -2
- data/ext/ffi_c/Platform.c +2 -2
- data/ext/ffi_c/Struct.c +1 -0
- data/ext/ffi_c/Variadic.c +2 -2
- data/ffi.gemspec +5 -5
- data/lib/ffi/library.rb +7 -7
- data/lib/ffi/platform.rb +4 -1
- data/lib/ffi/platform/x86_64-netbsd/types.conf +2 -0
- data/lib/ffi/struct.rb +2 -2
- data/lib/ffi/version.rb +1 -1
- data/libtest/ClosureTest.c +15 -0
- data/libtest/FunctionTest.c +12 -0
- data/spec/ffi/LICENSE.SPECS +22 -0
- data/spec/ffi/async_callback_spec.rb +1 -0
- data/spec/ffi/bool_spec.rb +2 -0
- data/spec/ffi/buffer_spec.rb +1 -0
- data/spec/ffi/callback_spec.rb +31 -4
- data/spec/ffi/custom_param_type.rb +1 -0
- data/spec/ffi/custom_type_spec.rb +1 -0
- data/spec/ffi/dup_spec.rb +1 -1
- data/spec/ffi/enum_spec.rb +1 -0
- data/spec/ffi/errno_spec.rb +2 -0
- data/spec/ffi/ffi_spec.rb +1 -0
- data/spec/ffi/fixtures/Benchmark.c +52 -0
- data/spec/ffi/fixtures/Benchmark.o +0 -0
- data/spec/ffi/fixtures/BoolTest.c +34 -0
- data/spec/ffi/fixtures/BoolTest.o +0 -0
- data/spec/ffi/fixtures/BufferTest.c +31 -0
- data/spec/ffi/fixtures/BufferTest.o +0 -0
- data/spec/ffi/fixtures/ClosureTest.c +190 -0
- data/spec/ffi/fixtures/ClosureTest.o +0 -0
- data/spec/ffi/fixtures/EnumTest.c +34 -0
- data/spec/ffi/fixtures/EnumTest.o +0 -0
- data/spec/ffi/fixtures/FunctionTest.c +58 -0
- data/spec/ffi/fixtures/FunctionTest.o +0 -0
- data/spec/ffi/fixtures/GNUmakefile +149 -0
- data/spec/ffi/fixtures/GlobalVariable.c +62 -0
- data/spec/ffi/fixtures/GlobalVariable.o +0 -0
- data/spec/ffi/fixtures/LastErrorTest.c +21 -0
- data/spec/ffi/fixtures/LastErrorTest.o +0 -0
- data/spec/ffi/fixtures/NumberTest.c +132 -0
- data/spec/ffi/fixtures/NumberTest.o +0 -0
- data/spec/ffi/fixtures/PointerTest.c +63 -0
- data/spec/ffi/fixtures/PointerTest.o +0 -0
- data/spec/ffi/fixtures/ReferenceTest.c +23 -0
- data/spec/ffi/fixtures/ReferenceTest.o +0 -0
- data/spec/ffi/fixtures/StringTest.c +34 -0
- data/spec/ffi/fixtures/StringTest.o +0 -0
- data/spec/ffi/fixtures/StructTest.c +243 -0
- data/spec/ffi/fixtures/StructTest.o +0 -0
- data/spec/ffi/fixtures/UnionTest.c +43 -0
- data/spec/ffi/fixtures/UnionTest.o +0 -0
- data/spec/ffi/fixtures/VariadicTest.c +99 -0
- data/spec/ffi/fixtures/VariadicTest.o +0 -0
- data/spec/ffi/fixtures/classes.rb +438 -0
- data/spec/ffi/function_spec.rb +4 -2
- data/spec/ffi/io_spec.rb +17 -0
- data/spec/ffi/library_spec.rb +25 -0
- data/spec/ffi/long_double.rb +1 -0
- data/spec/ffi/managed_struct_spec.rb +1 -1
- data/spec/ffi/memorypointer_spec.rb +72 -0
- data/spec/ffi/number_spec.rb +2 -0
- data/spec/ffi/platform_spec.rb +97 -0
- data/spec/ffi/pointer_spec.rb +8 -2
- data/spec/ffi/rbx/attach_function_spec.rb +6 -0
- data/spec/ffi/rbx/memory_pointer_spec.rb +7 -2
- data/spec/ffi/rbx/spec_helper.rb +7 -1
- data/spec/ffi/rbx/struct_spec.rb +7 -1
- data/spec/ffi/spec_helper.rb +68 -9
- data/spec/ffi/string_spec.rb +3 -1
- data/spec/ffi/strptr_spec.rb +1 -0
- data/spec/ffi/struct_by_ref_spec.rb +4 -3
- data/spec/ffi/struct_callback_spec.rb +2 -1
- data/spec/ffi/struct_initialize_spec.rb +1 -0
- data/spec/ffi/struct_packed_spec.rb +1 -0
- data/spec/ffi/struct_spec.rb +99 -39
- data/spec/ffi/typedef_spec.rb +15 -3
- data/spec/ffi/union_spec.rb +1 -0
- data/spec/ffi/variadic_spec.rb +18 -0
- data/spec/spec.opts +1 -2
- metadata +129 -94
data/spec/ffi/strptr_spec.rb
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
#
|
5
5
|
|
6
6
|
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
7
|
+
require 'ffi'
|
7
8
|
|
8
9
|
describe FFI::Struct, ' by_ref' do
|
9
10
|
before :all do
|
@@ -11,10 +12,10 @@ describe FFI::Struct, ' by_ref' do
|
|
11
12
|
layout :a, :pointer
|
12
13
|
end
|
13
14
|
|
14
|
-
@api = Module.new do
|
15
|
+
@api = Module.new do
|
15
16
|
extend FFI::Library
|
16
17
|
ffi_lib TestLibrary::PATH
|
17
|
-
fn = FFI::Type::POINTER.size == FFI::Type::LONG.size ? :ret_ulong :
|
18
|
+
fn = FFI::Type::POINTER.size == FFI::Type::LONG.size ? :ret_ulong : :ret_u64
|
18
19
|
attach_function :struct_test, fn, [ struct_class.by_ref ], :pointer
|
19
20
|
end
|
20
21
|
end
|
@@ -23,7 +24,7 @@ describe FFI::Struct, ' by_ref' do
|
|
23
24
|
s = @struct_class.new
|
24
25
|
@api.struct_test(s).should == s.pointer
|
25
26
|
end
|
26
|
-
|
27
|
+
|
27
28
|
it "should accept nil" do
|
28
29
|
@api.struct_test(nil).should == nil
|
29
30
|
end
|
@@ -4,6 +4,7 @@
|
|
4
4
|
#
|
5
5
|
|
6
6
|
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
7
|
+
require 'ffi'
|
7
8
|
|
8
9
|
describe FFI::Struct, ' with inline callback functions' do
|
9
10
|
it 'should be able to define inline callback field' do
|
@@ -19,7 +20,7 @@ describe FFI::Struct, ' with inline callback functions' do
|
|
19
20
|
end
|
20
21
|
attach_function :struct_call_add_cb, [TestStruct, :int, :int], :int
|
21
22
|
attach_function :struct_call_sub_cb, [TestStruct, :int, :int], :int
|
22
|
-
end
|
23
|
+
end.should be_an_instance_of FFI::Function
|
23
24
|
end
|
24
25
|
it 'should take methods as callbacks' do
|
25
26
|
module CallbackMember2
|
data/spec/ffi/struct_spec.rb
CHANGED
@@ -4,6 +4,8 @@
|
|
4
4
|
#
|
5
5
|
|
6
6
|
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
7
|
+
require 'ffi'
|
8
|
+
|
7
9
|
describe "Struct tests" do
|
8
10
|
StructTypes = {
|
9
11
|
's8' => :char,
|
@@ -18,7 +20,12 @@ describe "Struct tests" do
|
|
18
20
|
extend FFI::Library
|
19
21
|
ffi_lib TestLibrary::PATH
|
20
22
|
attach_function :ptr_ret_pointer, [ :pointer, :int], :string
|
21
|
-
|
23
|
+
begin
|
24
|
+
attach_function :ptr_ret_int32_t, [ :pointer, :int ], :int
|
25
|
+
rescue FFI::NotFoundError
|
26
|
+
# NetBSD uses #define instead of typedef for these
|
27
|
+
attach_function :ptr_ret_int32_t, :ptr_ret___int32_t, [ :pointer, :int ], :int
|
28
|
+
end
|
22
29
|
attach_function :ptr_from_address, [ :ulong ], :pointer
|
23
30
|
attach_function :string_equals, [ :string, :string ], :int
|
24
31
|
[ 's8', 's16', 's32', 's64', 'f32', 'f64', 'long' ].each do |t|
|
@@ -61,7 +68,7 @@ describe "Struct tests" do
|
|
61
68
|
it "Struct#[:pointer]=struct" do
|
62
69
|
smp = FFI::MemoryPointer.new :pointer
|
63
70
|
s = PointerMember.new smp
|
64
|
-
lambda { s[:pointer] = s }.should_not raise_error
|
71
|
+
lambda { s[:pointer] = s }.should_not raise_error Exception
|
65
72
|
end
|
66
73
|
it "Struct#[:pointer]=nil" do
|
67
74
|
smp = FFI::MemoryPointer.new :pointer
|
@@ -121,21 +128,19 @@ describe "Struct tests" do
|
|
121
128
|
s[:b] = 0xfee1deadbeef
|
122
129
|
mp.get_int64(4).should == 0xfee1deadbeef
|
123
130
|
end
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
mp.get_int64(ll_off).should == 0xfee1deadbeef
|
138
|
-
end
|
131
|
+
|
132
|
+
it "Struct#layout withs with a hash of :name => type" do
|
133
|
+
class HashLayout < FFI::Struct
|
134
|
+
layout :a => :int, :b => :long_long
|
135
|
+
end
|
136
|
+
ll_off = (FFI::TYPE_UINT64.alignment == 4? 4 : 8)
|
137
|
+
HashLayout.size.should == (ll_off + 8)
|
138
|
+
mp = FFI::MemoryPointer.new(HashLayout.size)
|
139
|
+
s = HashLayout.new mp
|
140
|
+
s[:a] = 0x12345678
|
141
|
+
mp.get_int(0).should == 0x12345678
|
142
|
+
s[:b] = 0xfee1deadbeef
|
143
|
+
mp.get_int64(ll_off).should == 0xfee1deadbeef
|
139
144
|
end
|
140
145
|
|
141
146
|
it "subclass overrides initialize without calling super" do
|
@@ -163,7 +168,7 @@ describe "Struct tests" do
|
|
163
168
|
layout :c, :char
|
164
169
|
end
|
165
170
|
attach_function :struct_field_s8, [ TestStruct.in ], :char
|
166
|
-
end
|
171
|
+
end.should be_an_instance_of FFI::Function
|
167
172
|
end
|
168
173
|
it "Can use Struct subclass as IN parameter type" do
|
169
174
|
module StructParam2
|
@@ -173,7 +178,7 @@ describe "Struct tests" do
|
|
173
178
|
layout :c, :char
|
174
179
|
end
|
175
180
|
attach_function :struct_field_s8, [ TestStruct.in ], :char
|
176
|
-
end
|
181
|
+
end.should be_an_instance_of FFI::Function
|
177
182
|
end
|
178
183
|
it "Can use Struct subclass as OUT parameter type" do
|
179
184
|
module StructParam3
|
@@ -183,7 +188,7 @@ describe "Struct tests" do
|
|
183
188
|
layout :c, :char
|
184
189
|
end
|
185
190
|
attach_function :struct_field_s8, [ TestStruct.out ], :char
|
186
|
-
end
|
191
|
+
end.should be_an_instance_of FFI::Function
|
187
192
|
end
|
188
193
|
it "can be passed directly as a :pointer parameter" do
|
189
194
|
class TestStruct < FFI::Struct
|
@@ -261,7 +266,7 @@ describe "Struct tests" do
|
|
261
266
|
def test_num_field(type, v)
|
262
267
|
klass = Class.new(FFI::Struct)
|
263
268
|
klass.layout :v, type, :dummy, :long
|
264
|
-
|
269
|
+
|
265
270
|
s = klass.new
|
266
271
|
s[:v] = v
|
267
272
|
s.pointer.send("get_#{type.to_s}", 0).should == v
|
@@ -312,11 +317,11 @@ describe "Struct tests" do
|
|
312
317
|
extend FFI::Library
|
313
318
|
TestEnum = enum :test_enum, [:c1, 10, :c2, 20, :c3, 30, :c4, 40]
|
314
319
|
class TestStruct < FFI::Struct
|
315
|
-
layout :a, :int, :c, :test_enum,
|
320
|
+
layout :a, :int, :c, :test_enum,
|
316
321
|
:d, [ TestEnum, TestEnum.symbols.length ]
|
317
322
|
end
|
318
323
|
end
|
319
|
-
|
324
|
+
|
320
325
|
it ":enum field r/w" do
|
321
326
|
s = EnumFields::TestStruct.new
|
322
327
|
s[:c] = :c3
|
@@ -324,22 +329,22 @@ describe "Struct tests" do
|
|
324
329
|
s.pointer.get_uint(FFI::Type::INT32.size).should == 30
|
325
330
|
s[:c].should == :c3
|
326
331
|
end
|
327
|
-
|
332
|
+
|
328
333
|
it "array of :enum field" do
|
329
334
|
s = EnumFields::TestStruct.new
|
330
335
|
EnumFields::TestEnum.symbols.each_with_index do |val, i|
|
331
336
|
s[:d][i] = val
|
332
337
|
end
|
333
|
-
|
338
|
+
|
334
339
|
EnumFields::TestEnum.symbols.each_with_index do |val, i|
|
335
340
|
s.pointer.get_uint(FFI::Type::INT32.size * (2 + i)).should == EnumFields::TestEnum[val]
|
336
341
|
end
|
337
|
-
|
342
|
+
|
338
343
|
s[:d].each_with_index do |val, i|
|
339
344
|
val.should == EnumFields::TestEnum.symbols[i]
|
340
345
|
end
|
341
346
|
end
|
342
|
-
|
347
|
+
|
343
348
|
module CallbackMember
|
344
349
|
extend FFI::Library
|
345
350
|
ffi_lib TestLibrary::PATH
|
@@ -396,6 +401,58 @@ describe "Struct tests" do
|
|
396
401
|
end
|
397
402
|
end
|
398
403
|
|
404
|
+
describe FFI::Struct, ".layout" do
|
405
|
+
module FFISpecs
|
406
|
+
module LibTest
|
407
|
+
extend FFI::Library
|
408
|
+
ffi_lib TestLibrary::PATH
|
409
|
+
begin
|
410
|
+
attach_function :ptr_ret_int32_t, [ :pointer, :int ], :int
|
411
|
+
rescue FFI::NotFoundError
|
412
|
+
# NetBSD uses #define instead of typedef for these
|
413
|
+
attach_function :ptr_ret_int32_t, :ptr_ret___int32_t, [ :pointer, :int ], :int
|
414
|
+
end
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
418
|
+
describe "when derived class is not assigned to any constant" do
|
419
|
+
it "resolves a built-in type" do
|
420
|
+
klass = Class.new FFI::Struct
|
421
|
+
klass.layout :number, :int
|
422
|
+
|
423
|
+
instance = klass.new
|
424
|
+
instance[:number] = 0xA1
|
425
|
+
FFISpecs::LibTest.ptr_ret_int32_t(instance, 0).should == 0xA1
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
429
|
+
describe "when derived class is assigned to a constant" do
|
430
|
+
it "resolves a built-in type" do
|
431
|
+
class FFISpecs::TestStruct < FFI::Struct
|
432
|
+
layout :number, :int
|
433
|
+
end
|
434
|
+
|
435
|
+
instance = FFISpecs::TestStruct.new
|
436
|
+
instance[:number] = 0xA1
|
437
|
+
FFISpecs::LibTest.ptr_ret_int32_t(instance, 0).should == 0xA1
|
438
|
+
end
|
439
|
+
|
440
|
+
it "resolves a type from the enclosing module" do
|
441
|
+
module FFISpecs::LibTest
|
442
|
+
typedef :uint, :custom_int
|
443
|
+
|
444
|
+
class TestStruct < FFI::Struct
|
445
|
+
layout :number, :custom_int
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
449
|
+
instance = FFISpecs::LibTest::TestStruct.new
|
450
|
+
instance[:number] = 0xA1
|
451
|
+
FFISpecs::LibTest.ptr_ret_int32_t(instance, 0).should == 0xA1
|
452
|
+
end
|
453
|
+
end
|
454
|
+
end
|
455
|
+
|
399
456
|
describe FFI::Struct, ' with a nested struct field' do
|
400
457
|
module LibTest
|
401
458
|
extend FFI::Library
|
@@ -420,7 +477,7 @@ describe FFI::Struct, ' with a nested struct field' do
|
|
420
477
|
LibTest::ContainerStruct.size.should == 8
|
421
478
|
end
|
422
479
|
it 'should return a Struct object when the field is accessed' do
|
423
|
-
@cs[:ns].is_a?(FFI::Struct).should be_true
|
480
|
+
@cs[:ns].is_a?(FFI::Struct).should be_true
|
424
481
|
end
|
425
482
|
it 'should read a value from memory' do
|
426
483
|
@cs = LibTest::ContainerStruct.new(LibTest.struct_make_container_struct(123))
|
@@ -432,7 +489,7 @@ describe FFI::Struct, ' with a nested struct field' do
|
|
432
489
|
LibTest.struct_align_nested_struct(@cs.to_ptr).should == 456
|
433
490
|
end
|
434
491
|
|
435
|
-
it 'should be able to assign struct instance to nested field' do
|
492
|
+
it 'should be able to assign struct instance to nested field' do
|
436
493
|
cs = LibTest::ContainerStruct.new(LibTest.struct_make_container_struct(123))
|
437
494
|
ns = LibTest::NestedStruct.new
|
438
495
|
ns[:i] = 567
|
@@ -540,15 +597,18 @@ describe FFI::Struct, ' by value' do
|
|
540
597
|
s = LibTest::S8S32.new
|
541
598
|
s[:s8] = 0x12
|
542
599
|
s[:s32] = 0x34567890
|
543
|
-
|
600
|
+
|
544
601
|
LibTest.struct_s8s32_s32_ret_s32(s, 0x1eefdead).should == 0x1eefdead
|
545
602
|
end
|
546
603
|
|
547
|
-
it 'parameter with following s64' do
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
604
|
+
# it 'parameter with following s64' do
|
605
|
+
# s = LibTest::S8S64.new
|
606
|
+
# s[:s8] = 0x12
|
607
|
+
# s[:s64] = 0x34567890
|
608
|
+
#
|
609
|
+
#
|
610
|
+
# LibTest.struct_s8s64_s64_ret_s64(s, 0x1eefdead1eefdead).should == 0x1eefdead1eefdead
|
611
|
+
# end
|
552
612
|
|
553
613
|
it 'parameter with preceding s32,ptr,s32' do
|
554
614
|
s = LibTest::S8S32.new
|
@@ -615,7 +675,7 @@ describe FFI::Struct, ' with an array field' do
|
|
615
675
|
end
|
616
676
|
it 'should allow iteration through the array elements' do
|
617
677
|
@s = LibTest::StructWithArray.new(LibTest.struct_make_struct_with_array(0, 1, 2, 3, 4))
|
618
|
-
@s[:a].each_with_index { |elem, i| elem.should == i }
|
678
|
+
@s[:a].each_with_index { |elem, i| elem.should == i }
|
619
679
|
end
|
620
680
|
it 'should return the pointer to the array' do
|
621
681
|
@s = LibTest::StructWithArray.new(LibTest.struct_make_struct_with_array(0, 1, 2, 3, 4))
|
@@ -652,7 +712,7 @@ describe 'BuggedStruct' do
|
|
652
712
|
end
|
653
713
|
it 'should return correct field/offset pairs' do
|
654
714
|
LibTest::BuggedStruct.offsets.sort do |a, b|
|
655
|
-
a[1] <=> b[1]
|
715
|
+
a[1] <=> b[1]
|
656
716
|
end.should == [[:visible, 0], [:x, 4], [:y, 8], [:rx, 12], [:ry, 14], [:order, 16], [:size, 17]]
|
657
717
|
end
|
658
718
|
end
|
@@ -702,7 +762,7 @@ describe "Struct allocation" do
|
|
702
762
|
end
|
703
763
|
struct = c.new
|
704
764
|
struct[:b] = ! struct[:b]
|
705
|
-
end.should_not raise_error
|
765
|
+
end.should_not raise_error Exception
|
706
766
|
end
|
707
767
|
|
708
768
|
end
|
@@ -713,7 +773,7 @@ describe "variable-length arrays" do
|
|
713
773
|
Class.new(FFI::Struct) do
|
714
774
|
layout :count, :int, :data, [ :char, 0 ]
|
715
775
|
end
|
716
|
-
}.should_not raise_error
|
776
|
+
}.should_not raise_error Exception
|
717
777
|
end
|
718
778
|
|
719
779
|
it "zero length array before last element should raise error" do
|
data/spec/ffi/typedef_spec.rb
CHANGED
@@ -4,6 +4,8 @@
|
|
4
4
|
#
|
5
5
|
|
6
6
|
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
7
|
+
require 'ffi'
|
8
|
+
|
7
9
|
describe "Custom type definitions" do
|
8
10
|
it "attach_function with custom typedef" do
|
9
11
|
module CustomTypedef
|
@@ -60,7 +62,12 @@ describe "Custom type definitions" do
|
|
60
62
|
typedef :int, :bar
|
61
63
|
|
62
64
|
ffi_lib TestLibrary::PATH
|
63
|
-
|
65
|
+
begin
|
66
|
+
attach_function :ptr_ret_int32_t, [ :string, :foo ], :bar
|
67
|
+
rescue FFI::NotFoundError
|
68
|
+
# NetBSD uses #define instead of typedef for these
|
69
|
+
attach_function :ptr_ret_int32_t, :ptr_ret___int32_t, [ :string, :foo ], :bar
|
70
|
+
end
|
64
71
|
end
|
65
72
|
end.should_not raise_error
|
66
73
|
end
|
@@ -70,8 +77,13 @@ describe "Custom type definitions" do
|
|
70
77
|
Module.new do
|
71
78
|
extend FFI::Library
|
72
79
|
ffi_lib "c"
|
73
|
-
|
74
|
-
|
80
|
+
if FFI::Platform.windows?
|
81
|
+
# _read() is a function of msvcrt.dll
|
82
|
+
attach_function :_read, [:int, :pointer, :uint], :int
|
83
|
+
else
|
84
|
+
# read(2) is a standard UNIX function
|
85
|
+
attach_function :read, [:int, :pointer, :size_t], :ssize_t
|
86
|
+
end
|
75
87
|
end
|
76
88
|
end.should_not raise_error
|
77
89
|
end
|
data/spec/ffi/union_spec.rb
CHANGED
data/spec/ffi/variadic_spec.rb
CHANGED
@@ -4,12 +4,30 @@
|
|
4
4
|
#
|
5
5
|
|
6
6
|
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
7
|
+
require 'ffi'
|
8
|
+
|
7
9
|
describe "Function with variadic arguments" do
|
8
10
|
module LibTest
|
9
11
|
extend FFI::Library
|
10
12
|
ffi_lib TestLibrary::PATH
|
13
|
+
enum :enum_type1, [:c1, :c2]
|
14
|
+
enum :enum_type2, [:c3, 42, :c4]
|
11
15
|
attach_function :pack_varargs, [ :buffer_out, :string, :varargs ], :void
|
16
|
+
attach_function :pack_varargs2, [ :buffer_out, :enum_type1, :string, :varargs ], :enum_type1
|
17
|
+
end
|
18
|
+
|
19
|
+
it "takes enum arguments" do
|
20
|
+
buf = FFI::Buffer.new :long_long, 2
|
21
|
+
LibTest.pack_varargs(buf, "ii", :int, :c3, :int, :c4)
|
22
|
+
buf.get_int64(0).should == 42
|
23
|
+
buf.get_int64(8).should == 43
|
12
24
|
end
|
25
|
+
|
26
|
+
it "returns symbols for enums" do
|
27
|
+
buf = FFI::Buffer.new :long_long, 2
|
28
|
+
LibTest.pack_varargs2(buf, :c1, "ii", :int, :c3, :int, :c4).should eql(:c2)
|
29
|
+
end
|
30
|
+
|
13
31
|
[ 0, 127, -128, -1 ].each do |i|
|
14
32
|
it "call variadic with (:char (#{i})) argument" do
|
15
33
|
buf = FFI::Buffer.new :long_long
|
data/spec/spec.opts
CHANGED
metadata
CHANGED
@@ -1,71 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ffi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.9.
|
4
|
+
version: 1.9.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wayne Meissner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-09-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '10.1'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '10.1'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake-compiler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: '0.9'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.
|
40
|
+
version: '0.9'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 2.14.1
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 2.14.1
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rubygems-tasks
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 0.2.4
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 0.2.4
|
69
69
|
description: Ruby FFI library
|
70
70
|
email: wmeissner@gmail.com
|
71
71
|
executables: []
|
@@ -73,9 +73,8 @@ extensions:
|
|
73
73
|
- ext/ffi_c/extconf.rb
|
74
74
|
extra_rdoc_files: []
|
75
75
|
files:
|
76
|
-
- ffi.gemspec
|
77
|
-
- LICENSE
|
78
76
|
- COPYING
|
77
|
+
- LICENSE
|
79
78
|
- README.md
|
80
79
|
- Rakefile
|
81
80
|
- ext/ffi_c/AbstractMemory.c
|
@@ -87,24 +86,62 @@ files:
|
|
87
86
|
- ext/ffi_c/Call.h
|
88
87
|
- ext/ffi_c/ClosurePool.c
|
89
88
|
- ext/ffi_c/ClosurePool.h
|
90
|
-
- ext/ffi_c/compat.h
|
91
89
|
- ext/ffi_c/DataConverter.c
|
92
90
|
- ext/ffi_c/DynamicLibrary.c
|
93
91
|
- ext/ffi_c/DynamicLibrary.h
|
94
|
-
- ext/ffi_c/extconf.rb
|
95
|
-
- ext/ffi_c/ffi.c
|
96
92
|
- ext/ffi_c/Function.c
|
97
93
|
- ext/ffi_c/Function.h
|
98
94
|
- ext/ffi_c/FunctionInfo.c
|
99
95
|
- ext/ffi_c/LastError.c
|
100
96
|
- ext/ffi_c/LastError.h
|
101
|
-
- ext/ffi_c/
|
102
|
-
- ext/ffi_c/
|
103
|
-
- ext/ffi_c/
|
97
|
+
- ext/ffi_c/LongDouble.c
|
98
|
+
- ext/ffi_c/LongDouble.h
|
99
|
+
- ext/ffi_c/MappedType.c
|
100
|
+
- ext/ffi_c/MappedType.h
|
101
|
+
- ext/ffi_c/MemoryPointer.c
|
102
|
+
- ext/ffi_c/MemoryPointer.h
|
103
|
+
- ext/ffi_c/MethodHandle.c
|
104
|
+
- ext/ffi_c/MethodHandle.h
|
105
|
+
- ext/ffi_c/Platform.c
|
106
|
+
- ext/ffi_c/Platform.h
|
107
|
+
- ext/ffi_c/Pointer.c
|
108
|
+
- ext/ffi_c/Pointer.h
|
109
|
+
- ext/ffi_c/Struct.c
|
110
|
+
- ext/ffi_c/Struct.h
|
111
|
+
- ext/ffi_c/StructByReference.c
|
112
|
+
- ext/ffi_c/StructByReference.h
|
113
|
+
- ext/ffi_c/StructByValue.c
|
114
|
+
- ext/ffi_c/StructByValue.h
|
115
|
+
- ext/ffi_c/StructLayout.c
|
116
|
+
- ext/ffi_c/Thread.c
|
117
|
+
- ext/ffi_c/Thread.h
|
118
|
+
- ext/ffi_c/Type.c
|
119
|
+
- ext/ffi_c/Type.h
|
120
|
+
- ext/ffi_c/Types.c
|
121
|
+
- ext/ffi_c/Types.h
|
122
|
+
- ext/ffi_c/Variadic.c
|
123
|
+
- ext/ffi_c/compat.h
|
124
|
+
- ext/ffi_c/extconf.rb
|
125
|
+
- ext/ffi_c/ffi.c
|
126
|
+
- ext/ffi_c/libffi.bsd.mk
|
127
|
+
- ext/ffi_c/libffi.darwin.mk
|
128
|
+
- ext/ffi_c/libffi.gnu.mk
|
129
|
+
- ext/ffi_c/libffi.mk
|
130
|
+
- ext/ffi_c/libffi.vc.mk
|
131
|
+
- ext/ffi_c/libffi.vc64.mk
|
104
132
|
- ext/ffi_c/libffi/ChangeLog
|
105
133
|
- ext/ffi_c/libffi/ChangeLog.libffi
|
106
134
|
- ext/ffi_c/libffi/ChangeLog.libgcj
|
107
135
|
- ext/ffi_c/libffi/ChangeLog.v1
|
136
|
+
- ext/ffi_c/libffi/LICENSE
|
137
|
+
- ext/ffi_c/libffi/Makefile.am
|
138
|
+
- ext/ffi_c/libffi/Makefile.in
|
139
|
+
- ext/ffi_c/libffi/Makefile.vc
|
140
|
+
- ext/ffi_c/libffi/Makefile.vc64
|
141
|
+
- ext/ffi_c/libffi/README
|
142
|
+
- ext/ffi_c/libffi/acinclude.m4
|
143
|
+
- ext/ffi_c/libffi/aclocal.m4
|
144
|
+
- ext/ffi_c/libffi/build-ios.sh
|
108
145
|
- ext/ffi_c/libffi/compile
|
109
146
|
- ext/ffi_c/libffi/config.guess
|
110
147
|
- ext/ffi_c/libffi/config.sub
|
@@ -118,16 +155,15 @@ files:
|
|
118
155
|
- ext/ffi_c/libffi/doc/version.texi
|
119
156
|
- ext/ffi_c/libffi/fficonfig.h.in
|
120
157
|
- ext/ffi_c/libffi/fficonfig.hw
|
158
|
+
- ext/ffi_c/libffi/include/Makefile.am
|
159
|
+
- ext/ffi_c/libffi/include/Makefile.in
|
121
160
|
- ext/ffi_c/libffi/include/ffi.h.in
|
122
161
|
- ext/ffi_c/libffi/include/ffi.h.vc
|
123
162
|
- ext/ffi_c/libffi/include/ffi.h.vc64
|
124
163
|
- ext/ffi_c/libffi/include/ffi_common.h
|
125
|
-
- ext/ffi_c/libffi/include/Makefile.am
|
126
|
-
- ext/ffi_c/libffi/include/Makefile.in
|
127
164
|
- ext/ffi_c/libffi/install-sh
|
128
165
|
- ext/ffi_c/libffi/libffi.pc.in
|
129
166
|
- ext/ffi_c/libffi/libtool-version
|
130
|
-
- ext/ffi_c/libffi/LICENSE
|
131
167
|
- ext/ffi_c/libffi/ltmain.sh
|
132
168
|
- ext/ffi_c/libffi/m4/ax_cc_maxopt.m4
|
133
169
|
- ext/ffi_c/libffi/m4/ax_cflags_warn_all.m4
|
@@ -142,19 +178,14 @@ files:
|
|
142
178
|
- ext/ffi_c/libffi/m4/ltsugar.m4
|
143
179
|
- ext/ffi_c/libffi/m4/ltversion.m4
|
144
180
|
- ext/ffi_c/libffi/m4/lt~obsolete.m4
|
145
|
-
- ext/ffi_c/libffi/Makefile.am
|
146
|
-
- ext/ffi_c/libffi/Makefile.in
|
147
|
-
- ext/ffi_c/libffi/Makefile.vc
|
148
|
-
- ext/ffi_c/libffi/Makefile.vc64
|
181
|
+
- ext/ffi_c/libffi/man/Makefile.am
|
182
|
+
- ext/ffi_c/libffi/man/Makefile.in
|
149
183
|
- ext/ffi_c/libffi/man/ffi.3
|
150
184
|
- ext/ffi_c/libffi/man/ffi_call.3
|
151
185
|
- ext/ffi_c/libffi/man/ffi_prep_cif.3
|
152
|
-
- ext/ffi_c/libffi/man/Makefile.am
|
153
|
-
- ext/ffi_c/libffi/man/Makefile.in
|
154
186
|
- ext/ffi_c/libffi/mdate-sh
|
155
187
|
- ext/ffi_c/libffi/missing
|
156
188
|
- ext/ffi_c/libffi/msvcc.sh
|
157
|
-
- ext/ffi_c/libffi/README
|
158
189
|
- ext/ffi_c/libffi/src/alpha/ffi.c
|
159
190
|
- ext/ffi_c/libffi/src/alpha/ffitarget.h
|
160
191
|
- ext/ffi_c/libffi/src/alpha/osf.S
|
@@ -234,6 +265,8 @@ files:
|
|
234
265
|
- ext/ffi_c/libffi/src/x86/unix64.S
|
235
266
|
- ext/ffi_c/libffi/src/x86/win32.S
|
236
267
|
- ext/ffi_c/libffi/src/x86/win64.S
|
268
|
+
- ext/ffi_c/libffi/testsuite/Makefile.am
|
269
|
+
- ext/ffi_c/libffi/testsuite/Makefile.in
|
237
270
|
- ext/ffi_c/libffi/testsuite/config/default.exp
|
238
271
|
- ext/ffi_c/libffi/testsuite/lib/libffi-dg.exp
|
239
272
|
- ext/ffi_c/libffi/testsuite/lib/libffi.exp
|
@@ -366,46 +399,14 @@ files:
|
|
366
399
|
- ext/ffi_c/libffi/testsuite/libffi.special/special.exp
|
367
400
|
- ext/ffi_c/libffi/testsuite/libffi.special/unwindtest.cc
|
368
401
|
- ext/ffi_c/libffi/testsuite/libffi.special/unwindtest_ffi_call.cc
|
369
|
-
- ext/ffi_c/libffi/testsuite/Makefile.am
|
370
|
-
- ext/ffi_c/libffi/testsuite/Makefile.in
|
371
402
|
- ext/ffi_c/libffi/texinfo.tex
|
372
|
-
- ext/ffi_c/libffi.bsd.mk
|
373
|
-
- ext/ffi_c/libffi.darwin.mk
|
374
|
-
- ext/ffi_c/libffi.gnu.mk
|
375
|
-
- ext/ffi_c/libffi.mk
|
376
|
-
- ext/ffi_c/libffi.vc.mk
|
377
|
-
- ext/ffi_c/libffi.vc64.mk
|
378
|
-
- ext/ffi_c/LongDouble.c
|
379
|
-
- ext/ffi_c/LongDouble.h
|
380
|
-
- ext/ffi_c/MappedType.c
|
381
|
-
- ext/ffi_c/MappedType.h
|
382
|
-
- ext/ffi_c/MemoryPointer.c
|
383
|
-
- ext/ffi_c/MemoryPointer.h
|
384
|
-
- ext/ffi_c/MethodHandle.c
|
385
|
-
- ext/ffi_c/MethodHandle.h
|
386
|
-
- ext/ffi_c/Platform.c
|
387
|
-
- ext/ffi_c/Platform.h
|
388
|
-
- ext/ffi_c/Pointer.c
|
389
|
-
- ext/ffi_c/Pointer.h
|
390
403
|
- ext/ffi_c/rbffi.h
|
391
404
|
- ext/ffi_c/rbffi_endian.h
|
392
|
-
- ext/ffi_c/Struct.c
|
393
|
-
- ext/ffi_c/Struct.h
|
394
|
-
- ext/ffi_c/StructByReference.c
|
395
|
-
- ext/ffi_c/StructByReference.h
|
396
|
-
- ext/ffi_c/StructByValue.c
|
397
|
-
- ext/ffi_c/StructByValue.h
|
398
|
-
- ext/ffi_c/StructLayout.c
|
399
|
-
- ext/ffi_c/Thread.c
|
400
|
-
- ext/ffi_c/Thread.h
|
401
|
-
- ext/ffi_c/Type.c
|
402
|
-
- ext/ffi_c/Type.h
|
403
|
-
- ext/ffi_c/Types.c
|
404
|
-
- ext/ffi_c/Types.h
|
405
|
-
- ext/ffi_c/Variadic.c
|
406
405
|
- ext/ffi_c/win32/stdbool.h
|
407
406
|
- ext/ffi_c/win32/stdint.h
|
407
|
+
- ffi.gemspec
|
408
408
|
- gen/Rakefile
|
409
|
+
- lib/ffi.rb
|
409
410
|
- lib/ffi/autopointer.rb
|
410
411
|
- lib/ffi/buffer.rb
|
411
412
|
- lib/ffi/callback.rb
|
@@ -416,6 +417,7 @@ files:
|
|
416
417
|
- lib/ffi/library.rb
|
417
418
|
- lib/ffi/managedstruct.rb
|
418
419
|
- lib/ffi/memorypointer.rb
|
420
|
+
- lib/ffi/platform.rb
|
419
421
|
- lib/ffi/platform/arm-linux/types.conf
|
420
422
|
- lib/ffi/platform/i386-cygwin/types.conf
|
421
423
|
- lib/ffi/platform/i386-darwin/types.conf
|
@@ -445,7 +447,6 @@ files:
|
|
445
447
|
- lib/ffi/platform/x86_64-openbsd/types.conf
|
446
448
|
- lib/ffi/platform/x86_64-solaris/types.conf
|
447
449
|
- lib/ffi/platform/x86_64-windows/types.conf
|
448
|
-
- lib/ffi/platform.rb
|
449
450
|
- lib/ffi/pointer.rb
|
450
451
|
- lib/ffi/struct.rb
|
451
452
|
- lib/ffi/struct_layout_builder.rb
|
@@ -458,7 +459,23 @@ files:
|
|
458
459
|
- lib/ffi/union.rb
|
459
460
|
- lib/ffi/variadic.rb
|
460
461
|
- lib/ffi/version.rb
|
461
|
-
-
|
462
|
+
- libtest/Benchmark.c
|
463
|
+
- libtest/BoolTest.c
|
464
|
+
- libtest/BufferTest.c
|
465
|
+
- libtest/ClosureTest.c
|
466
|
+
- libtest/EnumTest.c
|
467
|
+
- libtest/FunctionTest.c
|
468
|
+
- libtest/GNUmakefile
|
469
|
+
- libtest/GlobalVariable.c
|
470
|
+
- libtest/LastErrorTest.c
|
471
|
+
- libtest/NumberTest.c
|
472
|
+
- libtest/PointerTest.c
|
473
|
+
- libtest/ReferenceTest.c
|
474
|
+
- libtest/StringTest.c
|
475
|
+
- libtest/StructTest.c
|
476
|
+
- libtest/UnionTest.c
|
477
|
+
- libtest/VariadicTest.c
|
478
|
+
- spec/ffi/LICENSE.SPECS
|
462
479
|
- spec/ffi/async_callback_spec.rb
|
463
480
|
- spec/ffi/bool_spec.rb
|
464
481
|
- spec/ffi/buffer_spec.rb
|
@@ -469,11 +486,46 @@ files:
|
|
469
486
|
- spec/ffi/enum_spec.rb
|
470
487
|
- spec/ffi/errno_spec.rb
|
471
488
|
- spec/ffi/ffi_spec.rb
|
489
|
+
- spec/ffi/fixtures/Benchmark.c
|
490
|
+
- spec/ffi/fixtures/Benchmark.o
|
491
|
+
- spec/ffi/fixtures/BoolTest.c
|
492
|
+
- spec/ffi/fixtures/BoolTest.o
|
493
|
+
- spec/ffi/fixtures/BufferTest.c
|
494
|
+
- spec/ffi/fixtures/BufferTest.o
|
495
|
+
- spec/ffi/fixtures/ClosureTest.c
|
496
|
+
- spec/ffi/fixtures/ClosureTest.o
|
497
|
+
- spec/ffi/fixtures/EnumTest.c
|
498
|
+
- spec/ffi/fixtures/EnumTest.o
|
499
|
+
- spec/ffi/fixtures/FunctionTest.c
|
500
|
+
- spec/ffi/fixtures/FunctionTest.o
|
501
|
+
- spec/ffi/fixtures/GNUmakefile
|
502
|
+
- spec/ffi/fixtures/GlobalVariable.c
|
503
|
+
- spec/ffi/fixtures/GlobalVariable.o
|
504
|
+
- spec/ffi/fixtures/LastErrorTest.c
|
505
|
+
- spec/ffi/fixtures/LastErrorTest.o
|
506
|
+
- spec/ffi/fixtures/NumberTest.c
|
507
|
+
- spec/ffi/fixtures/NumberTest.o
|
508
|
+
- spec/ffi/fixtures/PointerTest.c
|
509
|
+
- spec/ffi/fixtures/PointerTest.o
|
510
|
+
- spec/ffi/fixtures/ReferenceTest.c
|
511
|
+
- spec/ffi/fixtures/ReferenceTest.o
|
512
|
+
- spec/ffi/fixtures/StringTest.c
|
513
|
+
- spec/ffi/fixtures/StringTest.o
|
514
|
+
- spec/ffi/fixtures/StructTest.c
|
515
|
+
- spec/ffi/fixtures/StructTest.o
|
516
|
+
- spec/ffi/fixtures/UnionTest.c
|
517
|
+
- spec/ffi/fixtures/UnionTest.o
|
518
|
+
- spec/ffi/fixtures/VariadicTest.c
|
519
|
+
- spec/ffi/fixtures/VariadicTest.o
|
520
|
+
- spec/ffi/fixtures/classes.rb
|
472
521
|
- spec/ffi/function_spec.rb
|
522
|
+
- spec/ffi/io_spec.rb
|
473
523
|
- spec/ffi/library_spec.rb
|
474
524
|
- spec/ffi/long_double.rb
|
475
525
|
- spec/ffi/managed_struct_spec.rb
|
526
|
+
- spec/ffi/memorypointer_spec.rb
|
476
527
|
- spec/ffi/number_spec.rb
|
528
|
+
- spec/ffi/platform_spec.rb
|
477
529
|
- spec/ffi/pointer_spec.rb
|
478
530
|
- spec/ffi/rbx/attach_function_spec.rb
|
479
531
|
- spec/ffi/rbx/memory_pointer_spec.rb
|
@@ -491,46 +543,29 @@ files:
|
|
491
543
|
- spec/ffi/union_spec.rb
|
492
544
|
- spec/ffi/variadic_spec.rb
|
493
545
|
- spec/spec.opts
|
494
|
-
- libtest/Benchmark.c
|
495
|
-
- libtest/BoolTest.c
|
496
|
-
- libtest/BufferTest.c
|
497
|
-
- libtest/ClosureTest.c
|
498
|
-
- libtest/EnumTest.c
|
499
|
-
- libtest/FunctionTest.c
|
500
|
-
- libtest/GlobalVariable.c
|
501
|
-
- libtest/GNUmakefile
|
502
|
-
- libtest/LastErrorTest.c
|
503
|
-
- libtest/NumberTest.c
|
504
|
-
- libtest/PointerTest.c
|
505
|
-
- libtest/ReferenceTest.c
|
506
|
-
- libtest/StringTest.c
|
507
|
-
- libtest/StructTest.c
|
508
|
-
- libtest/UnionTest.c
|
509
|
-
- libtest/VariadicTest.c
|
510
546
|
homepage: http://wiki.github.com/ffi/ffi
|
511
547
|
licenses:
|
512
548
|
- BSD
|
513
549
|
metadata: {}
|
514
550
|
post_install_message:
|
515
551
|
rdoc_options:
|
516
|
-
- --exclude=ext/ffi_c
|
517
|
-
- --exclude=ffi_c
|
552
|
+
- "--exclude=ext/ffi_c/.*\\.o$"
|
553
|
+
- "--exclude=ffi_c\\.(bundle|so)$"
|
518
554
|
require_paths:
|
519
555
|
- lib
|
520
|
-
- ext/ffi_c
|
521
556
|
required_ruby_version: !ruby/object:Gem::Requirement
|
522
557
|
requirements:
|
523
|
-
- -
|
558
|
+
- - ">="
|
524
559
|
- !ruby/object:Gem::Version
|
525
560
|
version: 1.8.7
|
526
561
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
527
562
|
requirements:
|
528
|
-
- -
|
563
|
+
- - ">="
|
529
564
|
- !ruby/object:Gem::Version
|
530
565
|
version: '0'
|
531
566
|
requirements: []
|
532
567
|
rubyforge_project:
|
533
|
-
rubygems_version: 2.
|
568
|
+
rubygems_version: 2.2.2
|
534
569
|
signing_key:
|
535
570
|
specification_version: 4
|
536
571
|
summary: Ruby FFI
|