alinta-ffi 1.9.19

Sign up to get free protection for your applications and to get access to all the features.
Files changed (195) hide show
  1. checksums.yaml +7 -0
  2. data/COPYING +49 -0
  3. data/LICENSE +24 -0
  4. data/README.md +112 -0
  5. data/Rakefile +243 -0
  6. data/ext/ffi_c/AbstractMemory.c +1109 -0
  7. data/ext/ffi_c/AbstractMemory.h +175 -0
  8. data/ext/ffi_c/ArrayType.c +162 -0
  9. data/ext/ffi_c/ArrayType.h +59 -0
  10. data/ext/ffi_c/Buffer.c +365 -0
  11. data/ext/ffi_c/Call.c +517 -0
  12. data/ext/ffi_c/Call.h +110 -0
  13. data/ext/ffi_c/ClosurePool.c +283 -0
  14. data/ext/ffi_c/ClosurePool.h +57 -0
  15. data/ext/ffi_c/DataConverter.c +91 -0
  16. data/ext/ffi_c/DynamicLibrary.c +339 -0
  17. data/ext/ffi_c/DynamicLibrary.h +98 -0
  18. data/ext/ffi_c/Function.c +998 -0
  19. data/ext/ffi_c/Function.h +87 -0
  20. data/ext/ffi_c/FunctionInfo.c +271 -0
  21. data/ext/ffi_c/LastError.c +184 -0
  22. data/ext/ffi_c/LastError.h +47 -0
  23. data/ext/ffi_c/LongDouble.c +63 -0
  24. data/ext/ffi_c/LongDouble.h +51 -0
  25. data/ext/ffi_c/MappedType.c +168 -0
  26. data/ext/ffi_c/MappedType.h +59 -0
  27. data/ext/ffi_c/MemoryPointer.c +197 -0
  28. data/ext/ffi_c/MemoryPointer.h +53 -0
  29. data/ext/ffi_c/MethodHandle.c +358 -0
  30. data/ext/ffi_c/MethodHandle.h +55 -0
  31. data/ext/ffi_c/Platform.c +129 -0
  32. data/ext/ffi_c/Platform.h +45 -0
  33. data/ext/ffi_c/Pointer.c +508 -0
  34. data/ext/ffi_c/Pointer.h +63 -0
  35. data/ext/ffi_c/Struct.c +829 -0
  36. data/ext/ffi_c/Struct.h +106 -0
  37. data/ext/ffi_c/StructByReference.c +190 -0
  38. data/ext/ffi_c/StructByReference.h +50 -0
  39. data/ext/ffi_c/StructByValue.c +150 -0
  40. data/ext/ffi_c/StructByValue.h +55 -0
  41. data/ext/ffi_c/StructLayout.c +698 -0
  42. data/ext/ffi_c/Thread.c +352 -0
  43. data/ext/ffi_c/Thread.h +95 -0
  44. data/ext/ffi_c/Type.c +397 -0
  45. data/ext/ffi_c/Type.h +62 -0
  46. data/ext/ffi_c/Types.c +139 -0
  47. data/ext/ffi_c/Types.h +89 -0
  48. data/ext/ffi_c/Variadic.c +304 -0
  49. data/ext/ffi_c/compat.h +78 -0
  50. data/ext/ffi_c/extconf.rb +71 -0
  51. data/ext/ffi_c/ffi.c +98 -0
  52. data/ext/ffi_c/libffi.bsd.mk +40 -0
  53. data/ext/ffi_c/libffi.darwin.mk +105 -0
  54. data/ext/ffi_c/libffi.gnu.mk +32 -0
  55. data/ext/ffi_c/libffi.mk +18 -0
  56. data/ext/ffi_c/libffi.vc.mk +26 -0
  57. data/ext/ffi_c/libffi.vc64.mk +26 -0
  58. data/ext/ffi_c/rbffi.h +57 -0
  59. data/ext/ffi_c/rbffi_endian.h +59 -0
  60. data/ext/ffi_c/win32/stdbool.h +8 -0
  61. data/ext/ffi_c/win32/stdint.h +201 -0
  62. data/ffi.gemspec +23 -0
  63. data/gen/Rakefile +30 -0
  64. data/lib/ffi.rb +20 -0
  65. data/lib/ffi/autopointer.rb +203 -0
  66. data/lib/ffi/buffer.rb +4 -0
  67. data/lib/ffi/callback.rb +4 -0
  68. data/lib/ffi/enum.rb +296 -0
  69. data/lib/ffi/errno.rb +43 -0
  70. data/lib/ffi/ffi.rb +44 -0
  71. data/lib/ffi/io.rb +62 -0
  72. data/lib/ffi/library.rb +590 -0
  73. data/lib/ffi/managedstruct.rb +84 -0
  74. data/lib/ffi/memorypointer.rb +1 -0
  75. data/lib/ffi/platform.rb +164 -0
  76. data/lib/ffi/platform/aarch64-linux/types.conf +104 -0
  77. data/lib/ffi/platform/arm-linux/types.conf +104 -0
  78. data/lib/ffi/platform/i386-cygwin/types.conf +3 -0
  79. data/lib/ffi/platform/i386-darwin/types.conf +100 -0
  80. data/lib/ffi/platform/i386-freebsd/types.conf +152 -0
  81. data/lib/ffi/platform/i386-gnu/types.conf +107 -0
  82. data/lib/ffi/platform/i386-linux/types.conf +103 -0
  83. data/lib/ffi/platform/i386-netbsd/types.conf +126 -0
  84. data/lib/ffi/platform/i386-openbsd/types.conf +128 -0
  85. data/lib/ffi/platform/i386-solaris/types.conf +122 -0
  86. data/lib/ffi/platform/i386-windows/types.conf +105 -0
  87. data/lib/ffi/platform/ia64-linux/types.conf +104 -0
  88. data/lib/ffi/platform/mips-linux/types.conf +102 -0
  89. data/lib/ffi/platform/mips64el-linux/types.conf +104 -0
  90. data/lib/ffi/platform/mipsel-linux/types.conf +102 -0
  91. data/lib/ffi/platform/powerpc-aix/types.conf +180 -0
  92. data/lib/ffi/platform/powerpc-darwin/types.conf +100 -0
  93. data/lib/ffi/platform/powerpc-linux/types.conf +100 -0
  94. data/lib/ffi/platform/powerpc64-linux/types.conf +104 -0
  95. data/lib/ffi/platform/s390-linux/types.conf +102 -0
  96. data/lib/ffi/platform/s390x-linux/types.conf +102 -0
  97. data/lib/ffi/platform/sparc-linux/types.conf +102 -0
  98. data/lib/ffi/platform/sparc-solaris/types.conf +128 -0
  99. data/lib/ffi/platform/sparc64-linux/types.conf +102 -0
  100. data/lib/ffi/platform/sparcv9-solaris/types.conf +128 -0
  101. data/lib/ffi/platform/x86_64-cygwin/types.conf +3 -0
  102. data/lib/ffi/platform/x86_64-darwin/types.conf +126 -0
  103. data/lib/ffi/platform/x86_64-freebsd/types.conf +128 -0
  104. data/lib/ffi/platform/x86_64-linux/types.conf +102 -0
  105. data/lib/ffi/platform/x86_64-netbsd/types.conf +128 -0
  106. data/lib/ffi/platform/x86_64-openbsd/types.conf +134 -0
  107. data/lib/ffi/platform/x86_64-solaris/types.conf +122 -0
  108. data/lib/ffi/platform/x86_64-windows/types.conf +120 -0
  109. data/lib/ffi/pointer.rb +161 -0
  110. data/lib/ffi/struct.rb +371 -0
  111. data/lib/ffi/struct_layout_builder.rb +227 -0
  112. data/lib/ffi/tools/const_generator.rb +229 -0
  113. data/lib/ffi/tools/generator.rb +60 -0
  114. data/lib/ffi/tools/generator_task.rb +36 -0
  115. data/lib/ffi/tools/struct_generator.rb +194 -0
  116. data/lib/ffi/tools/types_generator.rb +134 -0
  117. data/lib/ffi/types.rb +194 -0
  118. data/lib/ffi/union.rb +43 -0
  119. data/lib/ffi/variadic.rb +78 -0
  120. data/lib/ffi/version.rb +4 -0
  121. data/libtest/Benchmark.c +52 -0
  122. data/libtest/BoolTest.c +34 -0
  123. data/libtest/BufferTest.c +31 -0
  124. data/libtest/ClosureTest.c +205 -0
  125. data/libtest/EnumTest.c +51 -0
  126. data/libtest/FunctionTest.c +70 -0
  127. data/libtest/GNUmakefile +149 -0
  128. data/libtest/GlobalVariable.c +62 -0
  129. data/libtest/LastErrorTest.c +21 -0
  130. data/libtest/NumberTest.c +132 -0
  131. data/libtest/PointerTest.c +63 -0
  132. data/libtest/ReferenceTest.c +23 -0
  133. data/libtest/StringTest.c +34 -0
  134. data/libtest/StructTest.c +243 -0
  135. data/libtest/UnionTest.c +43 -0
  136. data/libtest/VariadicTest.c +99 -0
  137. data/spec/ffi/LICENSE.SPECS +22 -0
  138. data/spec/ffi/async_callback_spec.rb +35 -0
  139. data/spec/ffi/bitmask_spec.rb +575 -0
  140. data/spec/ffi/bool_spec.rb +32 -0
  141. data/spec/ffi/buffer_spec.rb +279 -0
  142. data/spec/ffi/callback_spec.rb +773 -0
  143. data/spec/ffi/custom_param_type.rb +37 -0
  144. data/spec/ffi/custom_type_spec.rb +74 -0
  145. data/spec/ffi/dup_spec.rb +52 -0
  146. data/spec/ffi/enum_spec.rb +423 -0
  147. data/spec/ffi/errno_spec.rb +20 -0
  148. data/spec/ffi/ffi_spec.rb +28 -0
  149. data/spec/ffi/fixtures/Benchmark.c +52 -0
  150. data/spec/ffi/fixtures/BitmaskTest.c +51 -0
  151. data/spec/ffi/fixtures/BoolTest.c +34 -0
  152. data/spec/ffi/fixtures/BufferTest.c +31 -0
  153. data/spec/ffi/fixtures/ClosureTest.c +205 -0
  154. data/spec/ffi/fixtures/EnumTest.c +51 -0
  155. data/spec/ffi/fixtures/FunctionTest.c +142 -0
  156. data/spec/ffi/fixtures/GNUmakefile +149 -0
  157. data/spec/ffi/fixtures/GlobalVariable.c +62 -0
  158. data/spec/ffi/fixtures/LastErrorTest.c +21 -0
  159. data/spec/ffi/fixtures/NumberTest.c +132 -0
  160. data/spec/ffi/fixtures/PipeHelper.h +21 -0
  161. data/spec/ffi/fixtures/PipeHelperPosix.c +41 -0
  162. data/spec/ffi/fixtures/PipeHelperWindows.c +72 -0
  163. data/spec/ffi/fixtures/PointerTest.c +63 -0
  164. data/spec/ffi/fixtures/ReferenceTest.c +23 -0
  165. data/spec/ffi/fixtures/StringTest.c +34 -0
  166. data/spec/ffi/fixtures/StructTest.c +243 -0
  167. data/spec/ffi/fixtures/UnionTest.c +43 -0
  168. data/spec/ffi/fixtures/VariadicTest.c +99 -0
  169. data/spec/ffi/fixtures/classes.rb +438 -0
  170. data/spec/ffi/function_spec.rb +97 -0
  171. data/spec/ffi/io_spec.rb +16 -0
  172. data/spec/ffi/library_spec.rb +286 -0
  173. data/spec/ffi/long_double.rb +30 -0
  174. data/spec/ffi/managed_struct_spec.rb +68 -0
  175. data/spec/ffi/memorypointer_spec.rb +78 -0
  176. data/spec/ffi/number_spec.rb +247 -0
  177. data/spec/ffi/platform_spec.rb +114 -0
  178. data/spec/ffi/pointer_spec.rb +285 -0
  179. data/spec/ffi/rbx/attach_function_spec.rb +34 -0
  180. data/spec/ffi/rbx/memory_pointer_spec.rb +198 -0
  181. data/spec/ffi/rbx/spec_helper.rb +6 -0
  182. data/spec/ffi/rbx/struct_spec.rb +18 -0
  183. data/spec/ffi/spec_helper.rb +93 -0
  184. data/spec/ffi/string_spec.rb +118 -0
  185. data/spec/ffi/strptr_spec.rb +50 -0
  186. data/spec/ffi/struct_by_ref_spec.rb +43 -0
  187. data/spec/ffi/struct_callback_spec.rb +69 -0
  188. data/spec/ffi/struct_initialize_spec.rb +35 -0
  189. data/spec/ffi/struct_packed_spec.rb +50 -0
  190. data/spec/ffi/struct_spec.rb +882 -0
  191. data/spec/ffi/typedef_spec.rb +91 -0
  192. data/spec/ffi/union_spec.rb +67 -0
  193. data/spec/ffi/variadic_spec.rb +132 -0
  194. data/spec/spec.opts +4 -0
  195. metadata +309 -0
@@ -0,0 +1,97 @@
1
+ #
2
+ # This file is part of ruby-ffi.
3
+ # For licensing, see LICENSE.SPECS
4
+ #
5
+
6
+ require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
7
+
8
+ describe FFI::Function do
9
+ module LibTest
10
+ extend FFI::Library
11
+ ffi_lib TestLibrary::PATH
12
+ attach_function :testFunctionAdd, [:int, :int, :pointer], :int
13
+ end
14
+ before do
15
+ @libtest = FFI::DynamicLibrary.open(TestLibrary::PATH,
16
+ FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_GLOBAL)
17
+ end
18
+
19
+ it 'is initialized with a signature and a block' do
20
+ fn = FFI::Function.new(:int, []) { 5 }
21
+ expect(fn.call).to eql 5
22
+ end
23
+
24
+ it 'raises an error when passing a wrong signature' do
25
+ expect { FFI::Function.new([], :int).new { } }.to raise_error TypeError
26
+ end
27
+
28
+ it 'returns a native pointer' do
29
+ expect(FFI::Function.new(:int, []) { }).to be_a_kind_of FFI::Pointer
30
+ end
31
+
32
+ it 'can be used as callback from C passing to it a block' do
33
+ function_add = FFI::Function.new(:int, [:int, :int]) { |a, b| a + b }
34
+ expect(LibTest.testFunctionAdd(10, 10, function_add)).to eq(20)
35
+ end
36
+
37
+ it 'can be used as callback from C passing to it a Proc object' do
38
+ function_add = FFI::Function.new(:int, [:int, :int], Proc.new { |a, b| a + b })
39
+ expect(LibTest.testFunctionAdd(10, 10, function_add)).to eq(20)
40
+ end
41
+
42
+ it 'can be used to wrap an existing function pointer' do
43
+ expect(FFI::Function.new(:int, [:int, :int], @libtest.find_function('testAdd')).call(10, 10)).to eq(20)
44
+ end
45
+
46
+ it 'can be attached to a module' do
47
+ module Foo; end
48
+ fp = FFI::Function.new(:int, [:int, :int], @libtest.find_function('testAdd'))
49
+ fp.attach(Foo, 'add')
50
+ expect(Foo.add(10, 10)).to eq(20)
51
+ end
52
+
53
+ it 'can be used to extend an object' do
54
+ fp = FFI::Function.new(:int, [:int, :int], @libtest.find_function('testAdd'))
55
+ foo = Object.new
56
+ class << foo
57
+ def singleton_class
58
+ class << self; self; end
59
+ end
60
+ end
61
+ fp.attach(foo.singleton_class, 'add')
62
+ expect(foo.add(10, 10)).to eq(20)
63
+ end
64
+
65
+ it 'can wrap a blocking function' do
66
+ fpOpen = FFI::Function.new(:pointer, [ ], @libtest.find_function('testBlockingOpen'))
67
+ fpRW = FFI::Function.new(:char, [ :pointer, :char ], @libtest.find_function('testBlockingRW'), :blocking => true)
68
+ fpWR = FFI::Function.new(:char, [ :pointer, :char ], @libtest.find_function('testBlockingWR'), :blocking => true)
69
+ fpClose = FFI::Function.new(:void, [ :pointer ], @libtest.find_function('testBlockingClose'))
70
+ handle = fpOpen.call
71
+ expect(handle).not_to be_null
72
+ begin
73
+ thWR = Thread.new { fpWR.call(handle, 63) }
74
+ thRW = Thread.new { fpRW.call(handle, 64) }
75
+ expect(thWR.value).to eq(64)
76
+ expect(thRW.value).to eq(63)
77
+ ensure
78
+ fpClose.call(handle)
79
+ end
80
+ end
81
+
82
+ it 'autorelease flag is set to true by default' do
83
+ fp = FFI::Function.new(:int, [:int, :int], @libtest.find_function('testAdd'))
84
+ expect(fp.autorelease?).to be true
85
+ end
86
+
87
+ it 'can explicity free itself' do
88
+ fp = FFI::Function.new(:int, []) { }
89
+ fp.free
90
+ expect { fp.free }.to raise_error RuntimeError
91
+ end
92
+
93
+ it 'can\'t explicity free itself if not previously allocated' do
94
+ fp = FFI::Function.new(:int, [:int, :int], @libtest.find_function('testAdd'))
95
+ expect { fp.free }.to raise_error RuntimeError
96
+ end
97
+ end
@@ -0,0 +1,16 @@
1
+ #
2
+ # This file is part of ruby-ffi.
3
+ # For licensing, see LICENSE.SPECS
4
+ #
5
+
6
+ require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
7
+
8
+ if false # disabled for #390
9
+ describe "FFI::IO.for_fd" do
10
+ it "produces an IO wrapping the specified file descriptor" do
11
+ expect do
12
+ FFI::IO.for_fd(2, "r")
13
+ end.to_not raise_error
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,286 @@
1
+ #
2
+ # This file is part of ruby-ffi.
3
+ # For licensing, see LICENSE.SPECS
4
+ #
5
+
6
+ require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
7
+
8
+ describe "Library" do
9
+ describe ".enum_value" do
10
+ m = Module.new do
11
+ extend FFI::Library
12
+ enum :something, [:one, :two]
13
+ end
14
+
15
+ it "should return a value for a valid key" do
16
+ expect(m.enum_value(:one)).to eq(0)
17
+ expect(m.enum_value(:two)).to eq(1)
18
+ end
19
+
20
+ it "should return nil for an invalid key" do
21
+ expect(m.enum_value(:three)).to be nil
22
+ end
23
+ end
24
+
25
+ describe "#ffi_convention" do
26
+ it "defaults to :default" do
27
+ m = Module.new do
28
+ extend FFI::Library
29
+ end
30
+ expect(m.ffi_convention).to eq(:default)
31
+ end
32
+
33
+ it "should be settable" do
34
+ m = Module.new do
35
+ extend FFI::Library
36
+ end
37
+
38
+ expect(m.ffi_convention).to eq(:default)
39
+ m.ffi_convention :stdcall
40
+ expect(m.ffi_convention).to eq(:stdcall)
41
+ end
42
+ end
43
+
44
+ if FFI::Platform::OS =~ /windows|cygwin/ && FFI::Platform::ARCH == 'i386'
45
+ module LibTestStdcall
46
+ extend FFI::Library
47
+ ffi_lib TestLibrary::PATH
48
+ ffi_convention :stdcall
49
+
50
+ class StructUCDP < FFI::Struct
51
+ layout :a1, :uchar,
52
+ :a2, :double,
53
+ :a3, :pointer
54
+ end
55
+
56
+ attach_function :testStdcallManyParams, [ :pointer, :int8, :int16, :int32, :int64,
57
+ StructUCDP.by_value, StructUCDP.by_ref, :float, :double ], :void
58
+ end
59
+
60
+ it "adds stdcall decoration: testStdcallManyParams@64" do
61
+ s = LibTestStdcall::StructUCDP.new
62
+ po = FFI::MemoryPointer.new :long
63
+ LibTestStdcall.testStdcallManyParams po, 1, 2, 3, 4, s, s, 1.0, 2.0
64
+ end
65
+ end
66
+
67
+ describe "ffi_lib" do
68
+ it "empty name list should raise error" do
69
+ expect {
70
+ Module.new do |m|
71
+ m.extend FFI::Library
72
+ ffi_lib
73
+ end
74
+ }.to raise_error(LoadError)
75
+ end
76
+
77
+ end
78
+
79
+ unless RbConfig::CONFIG['target_os'] =~ /mswin|mingw/
80
+ it "attach_function with no library specified" do
81
+ expect {
82
+ Module.new do |m|
83
+ m.extend FFI::Library
84
+ attach_function :getpid, [ ], :uint
85
+ end
86
+ }.to raise_error
87
+ end
88
+
89
+ it "attach_function :getpid from this process" do
90
+ expect {
91
+ expect(Module.new do |m|
92
+ m.extend FFI::Library
93
+ ffi_lib FFI::Library::CURRENT_PROCESS
94
+ attach_function :getpid, [ ], :uint
95
+ end.getpid).to eq(Process.pid)
96
+ }.not_to raise_error
97
+ end
98
+
99
+ it "loads library using symbol" do
100
+ expect {
101
+ expect(Module.new do |m|
102
+ m.extend FFI::Library
103
+ ffi_lib :c
104
+ attach_function :getpid, [ ], :uint
105
+ end.getpid).to eq(Process.pid)
106
+ }.not_to raise_error
107
+ end
108
+
109
+ it "attach_function :getpid from [ 'c', 'libc.so.6'] " do
110
+ expect {
111
+ expect(Module.new do |m|
112
+ m.extend FFI::Library
113
+ ffi_lib [ 'c', 'libc.so.6' ]
114
+ attach_function :getpid, [ ], :uint
115
+ end.getpid).to eq(Process.pid)
116
+ }.not_to raise_error
117
+ end
118
+
119
+ it "attach_function :getpid from [ 'libc.so.6', 'c' ] " do
120
+ expect {
121
+ expect(Module.new do |m|
122
+ m.extend FFI::Library
123
+ ffi_lib [ 'libc.so.6', 'c' ]
124
+ attach_function :getpid, [ ], :uint
125
+ end.getpid).to eq(Process.pid)
126
+ }.not_to raise_error
127
+ end
128
+
129
+ it "attach_function :getpid from [ 'libfubar.so.0xdeadbeef', nil, 'c' ] " do
130
+ expect {
131
+ expect(Module.new do |m|
132
+ m.extend FFI::Library
133
+ ffi_lib [ 'libfubar.so.0xdeadbeef', nil, 'c' ]
134
+ attach_function :getpid, [ ], :uint
135
+ end.getpid).to eq(Process.pid)
136
+ }.not_to raise_error
137
+ end
138
+
139
+ it "attach_function :getpid from [ 'libfubar.so.0xdeadbeef' ] " do
140
+ expect {
141
+ expect(Module.new do |m|
142
+ m.extend FFI::Library
143
+ ffi_lib 'libfubar.so.0xdeadbeef'
144
+ attach_function :getpid, [ ], :uint
145
+ end.getpid).to eq(Process.pid)
146
+ }.to raise_error(LoadError)
147
+ end
148
+
149
+ it "attach_function :bool_return_true from [ File.expand_path(#{TestLibrary::PATH.inspect}) ]" do
150
+ mod = Module.new do |m|
151
+ m.extend FFI::Library
152
+ ffi_lib File.expand_path(TestLibrary::PATH)
153
+ attach_function :bool_return_true, [ ], :bool
154
+ end
155
+ expect(mod.bool_return_true).to be true
156
+ end
157
+ end
158
+
159
+ def gvar_lib(name, type)
160
+ Module.new do |m|
161
+ m.extend FFI::Library
162
+ ffi_lib TestLibrary::PATH
163
+ attach_variable :gvar, "gvar_#{name}", type
164
+ attach_function :get, "gvar_#{name}_get", [], type
165
+ attach_function :set, "gvar_#{name}_set", [ type ], :void
166
+ end
167
+ end
168
+
169
+ def gvar_test(name, type, val)
170
+ lib = gvar_lib(name, type)
171
+ lib.set(val)
172
+ expect(lib.gvar).to eq(val)
173
+ lib.set(0)
174
+ lib.gvar = val
175
+ expect(lib.get).to eq(val)
176
+ end
177
+
178
+ [ 0, 127, -128, -1 ].each do |i|
179
+ it ":char variable" do
180
+ gvar_test("s8", :char, i)
181
+ end
182
+ end
183
+
184
+ [ 0, 0x7f, 0x80, 0xff ].each do |i|
185
+ it ":uchar variable" do
186
+ gvar_test("u8", :uchar, i)
187
+ end
188
+ end
189
+
190
+ [ 0, 0x7fff, -0x8000, -1 ].each do |i|
191
+ it ":short variable" do
192
+ gvar_test("s16", :short, i)
193
+ end
194
+ end
195
+
196
+ [ 0, 0x7fff, 0x8000, 0xffff ].each do |i|
197
+ it ":ushort variable" do
198
+ gvar_test("u16", :ushort, i)
199
+ end
200
+ end
201
+
202
+ [ 0, 0x7fffffff, -0x80000000, -1 ].each do |i|
203
+ it ":int variable" do
204
+ gvar_test("s32", :int, i)
205
+ end
206
+ end
207
+
208
+ [ 0, 0x7fffffff, 0x80000000, 0xffffffff ].each do |i|
209
+ it ":uint variable" do
210
+ gvar_test("u32", :uint, i)
211
+ end
212
+ end
213
+
214
+ [ 0, 0x7fffffffffffffff, -0x8000000000000000, -1 ].each do |i|
215
+ it ":long_long variable" do
216
+ gvar_test("s64", :long_long, i)
217
+ end
218
+ end
219
+
220
+ [ 0, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff ].each do |i|
221
+ it ":ulong_long variable" do
222
+ gvar_test("u64", :ulong_long, i)
223
+ end
224
+ end
225
+
226
+ if FFI::Platform::LONG_SIZE == 32
227
+ [ 0, 0x7fffffff, -0x80000000, -1 ].each do |i|
228
+ it ":long variable" do
229
+ gvar_test("long", :long, i)
230
+ end
231
+ end
232
+
233
+ [ 0, 0x7fffffff, 0x80000000, 0xffffffff ].each do |i|
234
+ it ":ulong variable" do
235
+ gvar_test("ulong", :ulong, i)
236
+ end
237
+ end
238
+ else
239
+ [ 0, 0x7fffffffffffffff, -0x8000000000000000, -1 ].each do |i|
240
+ it ":long variable" do
241
+ gvar_test("long", :long, i)
242
+ end
243
+ end
244
+
245
+ [ 0, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff ].each do |i|
246
+ it ":ulong variable" do
247
+ gvar_test("ulong", :ulong, i)
248
+ end
249
+ end
250
+ end
251
+
252
+ it "Pointer variable" do
253
+ lib = gvar_lib("pointer", :pointer)
254
+ val = FFI::MemoryPointer.new :long
255
+ lib.set(val)
256
+ expect(lib.gvar).to eq(val)
257
+ lib.set(nil)
258
+ lib.gvar = val
259
+ expect(lib.get).to eq(val)
260
+ end
261
+
262
+ [ 0, 0x7fffffff, -0x80000000, -1 ].each do |i|
263
+ it "structure" do
264
+ class GlobalStruct < FFI::Struct
265
+ layout :data, :long
266
+ end
267
+
268
+ lib = Module.new do |m|
269
+ m.extend FFI::Library
270
+ ffi_lib TestLibrary::PATH
271
+ attach_variable :gvar, "gvar_gstruct", GlobalStruct
272
+ attach_function :get, "gvar_gstruct_get", [], GlobalStruct
273
+ attach_function :set, "gvar_gstruct_set", [ GlobalStruct ], :void
274
+ end
275
+
276
+ val = GlobalStruct.new
277
+ val[:data] = i
278
+ lib.set(val)
279
+ expect(lib.gvar[:data]).to eq(i)
280
+ val[:data] = 0
281
+ lib.gvar[:data] = i
282
+ val = GlobalStruct.new(lib.get)
283
+ expect(val[:data]).to eq(i)
284
+ end
285
+ end
286
+ end
@@ -0,0 +1,30 @@
1
+ #
2
+ # This file is part of ruby-ffi.
3
+ # For licensing, see LICENSE.SPECS
4
+ #
5
+
6
+ require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
7
+ require 'bigdecimal'
8
+
9
+ describe ":long_double arguments and return values" do
10
+ module LibTest
11
+ extend FFI::Library
12
+ ffi_lib TestLibrary::PATH
13
+ attach_function :add_f128, [ :long_double, :long_double ], :long_double
14
+ attach_function :ret_f128, [ :long_double ], :long_double
15
+ end
16
+
17
+ it "returns first parameter" do
18
+ expect(LibTest.ret_f128(0.1)).to be_within(0.01).of(0.1)
19
+ end
20
+
21
+ it "returns first parameter with high precision" do
22
+ ld = BigDecimal.new("1.234567890123456789")
23
+ tolerance = BigDecimal.new("0.0000000000000000001")
24
+ expect(LibTest.ret_f128(ld)).to be_within(tolerance).of(ld)
25
+ end
26
+
27
+ it "add two long double numbers" do
28
+ expect(LibTest.add_f128(0.1, 0.2)).to be_within(0.01).of(0.3)
29
+ end
30
+ end
@@ -0,0 +1,68 @@
1
+ #
2
+ # This file is part of ruby-ffi.
3
+ # For licensing, see LICENSE.SPECS
4
+ #
5
+
6
+ require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
7
+
8
+ describe "Managed Struct" do
9
+ include FFI
10
+ module ManagedStructTestLib
11
+ extend FFI::Library
12
+ ffi_lib TestLibrary::PATH
13
+ attach_function :ptr_from_address, [ FFI::Platform::ADDRESS_SIZE == 32 ? :uint : :ulong_long ], :pointer
14
+ end
15
+
16
+ it "should raise an error if release() is not defined" do
17
+ class NoRelease < FFI::ManagedStruct ; layout :i, :int; end
18
+ expect { NoRelease.new(ManagedStructTestLib.ptr_from_address(0x12345678)) }.to raise_error(NoMethodError)
19
+ end
20
+
21
+ it "should be the right class" do
22
+ class WhatClassAmI < FFI::ManagedStruct
23
+ layout :i, :int
24
+ def self.release
25
+ end
26
+ end
27
+
28
+ expect(WhatClassAmI.new(ManagedStructTestLib.ptr_from_address(0x12345678)).class).to eq(WhatClassAmI)
29
+ end
30
+
31
+ it "should build with self reference" do
32
+ class ClassWithSelfRef < FFI::ManagedStruct
33
+ layout :data, self.ptr
34
+ def self.release
35
+ end
36
+ end
37
+
38
+ expect(ClassWithSelfRef.new(ManagedStructTestLib.ptr_from_address(0x12345678)).class).to eq(ClassWithSelfRef)
39
+ end
40
+
41
+ # see #427
42
+ it "should release memory properly", :broken => true do
43
+ class PleaseReleaseMe < FFI::ManagedStruct
44
+ layout :i, :int
45
+ @@count = 0
46
+ def self.release
47
+ @@count += 1
48
+ end
49
+ def self.wait_gc(count)
50
+ loop = 5
51
+ while loop > 0 && @@count < count
52
+ loop -= 1
53
+ TestLibrary.force_gc
54
+ sleep 0.05 if @@count < count
55
+ end
56
+ end
57
+ end
58
+
59
+ loop_count = 30
60
+ wiggle_room = 5
61
+
62
+ expect(PleaseReleaseMe).to receive(:release).at_least(loop_count-wiggle_room).times
63
+ loop_count.times do
64
+ PleaseReleaseMe.new(ManagedStructTestLib.ptr_from_address(0x12345678))
65
+ end
66
+ PleaseReleaseMe.wait_gc loop_count
67
+ end
68
+ end