ffi 1.9.3-x64-mingw32 → 1.9.5-x64-mingw32

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 (73) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +13 -16
  3. data/ext/ffi_c/DynamicLibrary.c +9 -5
  4. data/ext/ffi_c/DynamicLibrary.h +49 -0
  5. data/ext/ffi_c/Function.c +4 -3
  6. data/ext/ffi_c/FunctionInfo.c +2 -2
  7. data/ext/ffi_c/Platform.c +2 -2
  8. data/ext/ffi_c/Struct.c +1 -0
  9. data/ext/ffi_c/Variadic.c +2 -2
  10. data/ffi.gemspec +5 -5
  11. data/lib/2.0/ffi_c.so +0 -0
  12. data/lib/ffi/library.rb +7 -7
  13. data/lib/ffi/platform.rb +4 -1
  14. data/lib/ffi/platform/x86_64-netbsd/types.conf +2 -0
  15. data/lib/ffi/struct.rb +2 -2
  16. data/lib/ffi/version.rb +1 -1
  17. data/libtest/ClosureTest.c +15 -0
  18. data/libtest/FunctionTest.c +12 -0
  19. data/spec/ffi/LICENSE.SPECS +22 -0
  20. data/spec/ffi/async_callback_spec.rb +1 -0
  21. data/spec/ffi/bool_spec.rb +2 -0
  22. data/spec/ffi/buffer_spec.rb +1 -0
  23. data/spec/ffi/callback_spec.rb +31 -4
  24. data/spec/ffi/custom_param_type.rb +1 -0
  25. data/spec/ffi/custom_type_spec.rb +1 -0
  26. data/spec/ffi/dup_spec.rb +1 -1
  27. data/spec/ffi/enum_spec.rb +1 -0
  28. data/spec/ffi/errno_spec.rb +2 -0
  29. data/spec/ffi/ffi_spec.rb +1 -0
  30. data/spec/ffi/fixtures/Benchmark.c +52 -0
  31. data/spec/ffi/fixtures/BoolTest.c +34 -0
  32. data/spec/ffi/fixtures/BufferTest.c +31 -0
  33. data/spec/ffi/fixtures/ClosureTest.c +190 -0
  34. data/spec/ffi/fixtures/EnumTest.c +34 -0
  35. data/spec/ffi/fixtures/FunctionTest.c +58 -0
  36. data/spec/ffi/fixtures/GNUmakefile +149 -0
  37. data/spec/ffi/fixtures/GlobalVariable.c +62 -0
  38. data/spec/ffi/fixtures/LastErrorTest.c +21 -0
  39. data/spec/ffi/fixtures/NumberTest.c +132 -0
  40. data/spec/ffi/fixtures/PointerTest.c +63 -0
  41. data/spec/ffi/fixtures/ReferenceTest.c +23 -0
  42. data/spec/ffi/fixtures/StringTest.c +34 -0
  43. data/spec/ffi/fixtures/StructTest.c +243 -0
  44. data/spec/ffi/fixtures/UnionTest.c +43 -0
  45. data/spec/ffi/fixtures/VariadicTest.c +99 -0
  46. data/spec/ffi/fixtures/classes.rb +438 -0
  47. data/spec/ffi/function_spec.rb +4 -2
  48. data/spec/ffi/io_spec.rb +17 -0
  49. data/spec/ffi/library_spec.rb +25 -0
  50. data/spec/ffi/long_double.rb +1 -0
  51. data/spec/ffi/managed_struct_spec.rb +1 -1
  52. data/spec/ffi/memorypointer_spec.rb +72 -0
  53. data/spec/ffi/number_spec.rb +2 -0
  54. data/spec/ffi/platform_spec.rb +97 -0
  55. data/spec/ffi/pointer_spec.rb +8 -2
  56. data/spec/ffi/rbx/attach_function_spec.rb +6 -0
  57. data/spec/ffi/rbx/memory_pointer_spec.rb +7 -2
  58. data/spec/ffi/rbx/spec_helper.rb +7 -1
  59. data/spec/ffi/rbx/struct_spec.rb +7 -1
  60. data/spec/ffi/spec_helper.rb +68 -9
  61. data/spec/ffi/string_spec.rb +3 -1
  62. data/spec/ffi/strptr_spec.rb +1 -0
  63. data/spec/ffi/struct_by_ref_spec.rb +4 -3
  64. data/spec/ffi/struct_callback_spec.rb +2 -1
  65. data/spec/ffi/struct_initialize_spec.rb +1 -0
  66. data/spec/ffi/struct_packed_spec.rb +1 -0
  67. data/spec/ffi/struct_spec.rb +99 -39
  68. data/spec/ffi/typedef_spec.rb +15 -3
  69. data/spec/ffi/union_spec.rb +1 -0
  70. data/spec/ffi/variadic_spec.rb +18 -0
  71. data/spec/spec.opts +1 -2
  72. metadata +417 -430
  73. data/lib/ffi_c.so +0 -0
@@ -0,0 +1,438 @@
1
+ module FFISpecs
2
+ #
3
+ # Callback fixtures
4
+ #
5
+ module LibTest
6
+ callback :cbVrS8, [ ], :char
7
+ callback :cbVrU8, [ ], :uchar
8
+ callback :cbVrS16, [ ], :short
9
+ callback :cbVrU16, [ ], :ushort
10
+ callback :cbVrS32, [ ], :int
11
+ callback :cbVrU32, [ ], :uint
12
+ callback :cbVrL, [ ], :long
13
+ callback :cbVrUL, [ ], :ulong
14
+ callback :cbVrS64, [ ], :long_long
15
+ callback :cbVrU64, [ ], :ulong_long
16
+ callback :cbVrP, [], :pointer
17
+ callback :cbCrV, [ :char ], :void
18
+ callback :cbSrV, [ :short ], :void
19
+ callback :cbIrV, [ :int ], :void
20
+ callback :cbLrV, [ :long ], :void
21
+ callback :cbULrV, [ :ulong ], :void
22
+ callback :cbLrV, [ :long_long ], :void
23
+
24
+ attach_function :testCallbackVrS8, :testClosureVrB, [ :cbVrS8 ], :char
25
+ attach_function :testCallbackVrU8, :testClosureVrB, [ :cbVrU8 ], :uchar
26
+ attach_function :testCallbackVrS16, :testClosureVrS, [ :cbVrS16 ], :short
27
+ attach_function :testCallbackVrU16, :testClosureVrS, [ :cbVrU16 ], :ushort
28
+ attach_function :testCallbackVrS32, :testClosureVrI, [ :cbVrS32 ], :int
29
+ attach_function :testCallbackVrU32, :testClosureVrI, [ :cbVrU32 ], :uint
30
+ attach_function :testCallbackVrL, :testClosureVrL, [ :cbVrL ], :long
31
+ attach_function :testCallbackVrUL, :testClosureVrL, [ :cbVrUL ], :ulong
32
+ attach_function :testCallbackVrS64, :testClosureVrLL, [ :cbVrS64 ], :long_long
33
+ attach_function :testCallbackVrU64, :testClosureVrLL, [ :cbVrU64 ], :ulong_long
34
+ attach_function :testCallbackVrP, :testClosureVrP, [ :cbVrP ], :pointer
35
+ attach_function :testCallbackCrV, :testClosureBrV, [ :cbCrV, :char ], :void
36
+ attach_variable :cbVrS8, :gvar_pointer, :cbVrS8
37
+ attach_variable :pVrS8, :gvar_pointer, :pointer
38
+ attach_function :testGVarCallbackVrS8, :testClosureVrB, [ :pointer ], :char
39
+ attach_function :testOptionalCallbackCrV, :testOptionalClosureBrV, [ :cbCrV, :char ], :void
40
+
41
+ attach_function :testCallbackVrS8, :testClosureVrB, [ callback([ ], :char) ], :char
42
+
43
+ callback :cb_return_type, [ :int ], :int
44
+ callback :cb_lookup, [ ], :cb_return_type
45
+ attach_function :testReturnsCallback, :testReturnsClosure, [ :cb_lookup, :int ], :int
46
+
47
+ callback :funcptr, [ :int ], :int
48
+ attach_function :testReturnsFunctionPointer, [ ], :funcptr
49
+
50
+ callback :cbS8rV, [ :char ], :void
51
+ callback :cbU8rV, [ :uchar ], :void
52
+ callback :cbS16rV, [ :short ], :void
53
+ callback :cbU16rV, [ :ushort ], :void
54
+
55
+ callback :cbS32rV, [ :int ], :void
56
+ callback :cbU32rV, [ :uint ], :void
57
+
58
+ callback :cbLrV, [ :long ], :void
59
+ callback :cbULrV, [ :ulong ], :void
60
+
61
+ callback :cbS64rV, [ :long_long ], :void
62
+ attach_function :testCallbackCrV, :testClosureBrV, [ :cbS8rV, :char ], :void
63
+ attach_function :testCallbackU8rV, :testClosureBrV, [ :cbU8rV, :uchar ], :void
64
+ attach_function :testCallbackSrV, :testClosureSrV, [ :cbS16rV, :short ], :void
65
+ attach_function :testCallbackU16rV, :testClosureSrV, [ :cbU16rV, :ushort ], :void
66
+ attach_function :testCallbackIrV, :testClosureIrV, [ :cbS32rV, :int ], :void
67
+ attach_function :testCallbackU32rV, :testClosureIrV, [ :cbU32rV, :uint ], :void
68
+
69
+ attach_function :testCallbackLrV, :testClosureLrV, [ :cbLrV, :long ], :void
70
+ attach_function :testCallbackULrV, :testClosureULrV, [ :cbULrV, :ulong ], :void
71
+
72
+ attach_function :testCallbackLLrV, :testClosureLLrV, [ :cbS64rV, :long_long ], :void
73
+ end
74
+
75
+ #
76
+ # Enum fixtures
77
+ #
78
+ module TestEnum0
79
+ extend FFI::Library
80
+ end
81
+
82
+ module TestEnum1
83
+ extend FFI::Library
84
+ ffi_lib LIBRARY
85
+
86
+ enum [:c1, :c2, :c3, :c4]
87
+ enum [:c5, 42, :c6, :c7, :c8]
88
+ enum [:c9, 42, :c10, :c11, 4242, :c12]
89
+ enum [:c13, 42, :c14, 4242, :c15, 424242, :c16, 42424242]
90
+
91
+ attach_function :test_untagged_enum, [:int], :int
92
+ end
93
+
94
+ module TestEnum3
95
+ extend FFI::Library
96
+ ffi_lib LIBRARY
97
+
98
+ enum :enum_type1, [:c1, :c2, :c3, :c4]
99
+ enum :enum_type2, [:c5, 42, :c6, :c7, :c8]
100
+ enum :enum_type3, [:c9, 42, :c10, :c11, 4242, :c12]
101
+ enum :enum_type4, [:c13, 42, :c14, 4242, :c15, 424242, :c16, 42424242]
102
+
103
+ attach_function :test_tagged_typedef_enum1, [:enum_type1], :enum_type1
104
+ attach_function :test_tagged_typedef_enum2, [:enum_type2], :enum_type2
105
+ attach_function :test_tagged_typedef_enum3, [:enum_type3], :enum_type3
106
+ attach_function :test_tagged_typedef_enum4, [:enum_type4], :enum_type4
107
+ end
108
+
109
+ #
110
+ # Errno fixtures
111
+ #
112
+ module LibTest
113
+ attach_function :setLastError, [ :int ], :void
114
+ end
115
+
116
+ #
117
+ # ManagedStruct fixtures
118
+ #
119
+ module LibTest
120
+ attach_function :ptr_from_address, [ FFI::Platform::ADDRESS_SIZE == 32 ? :uint : :ulong_long ], :pointer
121
+ end
122
+
123
+ class NoRelease < ManagedStruct
124
+ layout :i, :int
125
+ end
126
+
127
+ class WhatClassAmI < ManagedStruct
128
+ layout :i, :int
129
+ def self.release; end
130
+ end
131
+
132
+ class PleaseReleaseMe < ManagedStruct
133
+ layout :i, :int
134
+ @@count = 0
135
+ def self.release
136
+ @@count += 1
137
+ end
138
+ def self.wait_gc(count)
139
+ loop = 5
140
+ while loop > 0 && @@count < count
141
+ loop -= 1
142
+ if RUBY_PLATFORM =~ /java/
143
+ require 'java'
144
+ java.lang.System.gc
145
+ else
146
+ GC.start
147
+ end
148
+ sleep 0.05 if @@count < count
149
+ end
150
+ end
151
+ end
152
+
153
+ #
154
+ # Number fixtures
155
+ #
156
+ module LibTest
157
+ attach_function :ret_s8, [ :char ], :char
158
+ attach_function :ret_u8, [ :uchar ], :uchar
159
+ attach_function :ret_s16, [ :short ], :short
160
+ attach_function :ret_u16, [ :ushort ], :ushort
161
+ attach_function :ret_s32, [ :int ], :int
162
+ attach_function :ret_u32, [ :uint ], :uint
163
+ attach_function :ret_s64, [ :long_long ], :long_long
164
+ attach_function :ret_u64, [ :ulong_long ], :ulong_long
165
+ attach_function :ret_long, [ :long ], :long
166
+ attach_function :ret_ulong, [ :ulong ], :ulong
167
+ attach_function :set_s8, [ :char ], :void
168
+ attach_function :get_s8, [ ], :char
169
+ attach_function :set_float, [ :float ], :void
170
+ attach_function :get_float, [ ], :float
171
+ attach_function :set_double, [ :double ], :void
172
+ attach_function :get_double, [ ], :double
173
+ end
174
+
175
+ PACK_VALUES = {
176
+ 's8' => [ 0x12 ],
177
+ 'u8' => [ 0x34 ],
178
+ 's16' => [ 0x5678 ],
179
+ 'u16' => [ 0x9abc ],
180
+ 's32' => [ 0x7654321f ],
181
+ 'u32' => [ 0xfee1babe ],
182
+ 'sL' => [ 0x1f2e3d4c ],
183
+ 'uL' => [ 0xf7e8d9ca ],
184
+ 's64' => [ 0x1eafdeadbeefa1b2 ],
185
+ #'f32' => [ 1.234567 ], # TODO: Why is this disabled?
186
+ 'f64' => [ 9.87654321 ]
187
+ }
188
+
189
+ TYPE_MAP = {
190
+ 's8' => :char, 'u8' => :uchar, 's16' => :short, 'u16' => :ushort,
191
+ 's32' => :int, 'u32' => :uint, 's64' => :long_long, 'u64' => :ulong_long,
192
+ 'sL' => :long, 'uL' => :ulong, 'f32' => :float, 'f64' => :double
193
+ }
194
+ TYPES = TYPE_MAP.keys
195
+
196
+ module LibTest
197
+ [ 's32', 'u32', 's64', 'u64' ].each do |rt|
198
+ TYPES.each do |t1|
199
+ TYPES.each do |t2|
200
+ TYPES.each do |t3|
201
+ begin
202
+ attach_function "pack_#{t1}#{t2}#{t3}_#{rt}",
203
+ [ TYPE_MAP[t1], TYPE_MAP[t2], TYPE_MAP[t3], :buffer_out ], :void
204
+ rescue FFI::NotFoundError
205
+ end
206
+ end
207
+ end
208
+ end
209
+ end
210
+ end
211
+
212
+ #
213
+ # Pointer fixtures
214
+ #
215
+ module LibTest
216
+ attach_function :ptr_ret_int32_t, [ :pointer, :int ], :int
217
+ attach_function :ptr_from_address, [ FFI::Platform::ADDRESS_SIZE == 32 ? :uint : :ulong_long ], :pointer
218
+ attach_function :ptr_set_pointer, [ :pointer, :int, :pointer ], :void
219
+ end
220
+
221
+ class ToPtrTest
222
+ def initialize(ptr)
223
+ @ptr = ptr
224
+ end
225
+ def to_ptr
226
+ @ptr
227
+ end
228
+ end
229
+
230
+ require 'delegate'
231
+ class PointerDelegate < DelegateClass(FFI::Pointer)
232
+ def initialize(ptr)
233
+ super
234
+ @ptr = ptr
235
+ end
236
+ def to_ptr
237
+ @ptr
238
+ end
239
+ end
240
+
241
+ class AutoPointerTestHelper
242
+ @@count = 0
243
+ def self.release
244
+ @@count += 1 if @@count > 0
245
+ end
246
+ def self.reset
247
+ @@count = 0
248
+ end
249
+ def self.gc_everything(count)
250
+ loop = 5
251
+ while @@count < count && loop > 0
252
+ loop -= 1
253
+ if RUBY_PLATFORM =~ /java/
254
+ require "java"
255
+ java.lang.System.gc
256
+ else
257
+ GC.start
258
+ end
259
+ sleep 0.05 unless @@count == count
260
+ end
261
+ @@count = 0
262
+ end
263
+ def self.finalizer
264
+ self.method(:release).to_proc
265
+ end
266
+ end
267
+
268
+ #
269
+ # String fixtures
270
+ #
271
+ module LibTest
272
+ attach_function :ptr_ret_pointer, [ :pointer, :int], :string
273
+ attach_function :string_equals, [ :string, :string ], :int
274
+ attach_function :string_dummy, [ :string ], :void
275
+ end
276
+
277
+ #
278
+ # Struct initialize fixtures
279
+ #
280
+ class StructWithInitialize < FFI::Struct
281
+ layout :string, :string
282
+ attr_accessor :magic
283
+ def initialize
284
+ super
285
+ self.magic = 42
286
+ end
287
+ end
288
+
289
+ #
290
+ # Struct fixtures
291
+ #
292
+ StructTypes = {
293
+ 's8' => :char,
294
+ 's16' => :short,
295
+ 's32' => :int,
296
+ 's64' => :long_long,
297
+ 'long' => :long,
298
+ 'f32' => :float,
299
+ 'f64' => :double
300
+ }
301
+
302
+ module LibTest
303
+ attach_function :ptr_ret_pointer, [ :pointer, :int], :string
304
+ attach_function :ptr_ret_int32_t, [ :pointer, :int ], :int
305
+ attach_function :ptr_from_address, [ :ulong ], :pointer
306
+ attach_function :string_equals, [ :string, :string ], :int
307
+ [ 's8', 's16', 's32', 's64', 'f32', 'f64', 'long' ].each do |t|
308
+ attach_function "struct_align_#{t}", [ :pointer ], StructTypes[t]
309
+ end
310
+ end
311
+
312
+ class PointerMember < FFI::Struct
313
+ layout :pointer, :pointer
314
+ end
315
+
316
+ class StringMember < FFI::Struct
317
+ layout :string, :string
318
+ end
319
+
320
+ module CallbackMember
321
+ extend FFI::Library
322
+ ffi_lib LIBRARY
323
+ callback :add, [ :int, :int ], :int
324
+ callback :sub, [ :int, :int ], :int
325
+
326
+ class TestStruct < FFI::Struct
327
+ layout :add, :add,
328
+ :sub, :sub
329
+ end
330
+
331
+ attach_function :struct_call_add_cb, [TestStruct, :int, :int], :int
332
+ attach_function :struct_call_sub_cb, [TestStruct, :int, :int], :int
333
+ end
334
+
335
+ module LibTest
336
+ class NestedStruct < FFI::Struct
337
+ layout :i, :int
338
+ end
339
+
340
+ class ContainerStruct < FFI::Struct
341
+ layout :first, :char, :ns, NestedStruct
342
+ end
343
+
344
+ attach_function :struct_align_nested_struct, [ :pointer ], :int
345
+ attach_function :struct_make_container_struct, [ :int ], :pointer
346
+
347
+ class StructWithArray < FFI::Struct
348
+ layout :first, :char, :a, [:int, 5]
349
+ end
350
+
351
+ attach_function :struct_make_struct_with_array, [:int, :int, :int, :int, :int], :pointer
352
+ attach_function :struct_field_array, [:pointer], :pointer
353
+
354
+ class BuggedStruct < FFI::Struct
355
+ layout :visible, :uchar,
356
+ :x, :uint,
357
+ :y, :uint,
358
+ :rx, :short,
359
+ :ry, :short,
360
+ :order, :uchar,
361
+ :size, :uchar
362
+ end
363
+
364
+ attach_function :bugged_struct_size, [], :uint
365
+ end
366
+
367
+ module StructCustomTypedef
368
+ extend FFI::Library
369
+ ffi_lib LIBRARY
370
+ typedef :uint, :fubar3_t
371
+
372
+ class S < FFI::Struct
373
+ layout :a, :fubar3_t
374
+ end
375
+ end
376
+
377
+ #
378
+ # Union fixtures
379
+ #
380
+ module LibTest
381
+ Types = {
382
+ 's8' => [:char, :c, 1],
383
+ 's16' => [:short, :s, 0xff0],
384
+ 's32' => [:int, :i, 0xff00],
385
+ 's64' => [:long_long, :j, 0xffff00],
386
+ 'long' => [:long, :l, 0xffff],
387
+ 'f32' => [:float, :f, 1.0001],
388
+ 'f64' => [:double, :d, 1.000000001]
389
+ }
390
+
391
+ class TestUnion < FFI::Union
392
+ layout( :a, [:char, 10],
393
+ :i, :int,
394
+ :f, :float,
395
+ :d, :double,
396
+ :s, :short,
397
+ :l, :long,
398
+ :j, :long_long,
399
+ :c, :char )
400
+ end
401
+
402
+ Types.keys.each do |k|
403
+ attach_function "union_align_#{k}", [ :pointer ], Types[k][0]
404
+ attach_function "union_make_union_with_#{k}", [ Types[k][0] ], :pointer
405
+ end
406
+
407
+ attach_function :union_size, [], :uint
408
+ end
409
+
410
+ #
411
+ # Variadic fixtures
412
+ #
413
+ module LibTest
414
+ attach_function :pack_varargs, [ :buffer_out, :string, :varargs ], :void
415
+ end
416
+
417
+ module Varargs
418
+ PACK_VALUES = {
419
+ 'c' => [ 0x12 ],
420
+ 'C' => [ 0x34 ],
421
+ 's' => [ 0x5678 ],
422
+ 'S' => [ 0x9abc ],
423
+ 'i' => [ 0x7654321f ],
424
+ 'I' => [ 0xfee1babe ],
425
+ 'l' => [ 0x1f2e3d4c ],
426
+ 'L' => [ 0xf7e8d9ca ],
427
+ 'j' => [ 0x1eafdeadbeefa1b2 ],
428
+ 'f' => [ 1.23456789 ],
429
+ 'd' => [ 9.87654321 ]
430
+ }
431
+
432
+ TYPE_MAP = {
433
+ 'c' => :char, 'C' => :uchar, 's' => :short, 'S' => :ushort,
434
+ 'i' => :int, 'I' => :uint, 'j' => :long_long, 'J' => :ulong_long,
435
+ 'l' => :long, 'L' => :ulong, 'f' => :float, 'd' => :double
436
+ }
437
+ end
438
+ 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::Function do
9
10
  module LibTest
@@ -16,13 +17,14 @@ describe FFI::Function do
16
17
  FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_GLOBAL)
17
18
  end
18
19
  it 'is initialized with a signature and a block' do
19
- FFI::Function.new(:int, []) { }
20
+ fn = FFI::Function.new(:int, []) { 5 }
21
+ expect(fn.call).to eql 5
20
22
  end
21
23
  it 'raises an error when passing a wrong signature' do
22
24
  lambda { FFI::Function.new([], :int).new { } }.should raise_error TypeError
23
25
  end
24
26
  it 'returns a native pointer' do
25
- FFI::Function.new(:int, []) { }.kind_of? FFI::Pointer
27
+ expect(FFI::Function.new(:int, []) { }).to be_a_kind_of FFI::Pointer
26
28
  end
27
29
  it 'can be used as callback from C passing to it a block' do
28
30
  function_add = FFI::Function.new(:int, [:int, :int]) { |a, b| a + b }