ffi 0.3.5 → 0.4.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 (59) hide show
  1. data/README.rdoc +51 -1
  2. data/Rakefile +34 -26
  3. data/ext/ffi_c/AbstractMemory.c +73 -70
  4. data/ext/ffi_c/AbstractMemory.h +8 -4
  5. data/ext/ffi_c/AutoPointer.c +8 -9
  6. data/ext/ffi_c/AutoPointer.h +2 -2
  7. data/ext/ffi_c/Buffer.c +19 -20
  8. data/ext/ffi_c/Callback.c +85 -33
  9. data/ext/ffi_c/Callback.h +11 -5
  10. data/ext/ffi_c/{NativeLibrary.c → DynamicLibrary.c} +83 -16
  11. data/ext/ffi_c/{NativeLibrary.h → DynamicLibrary.h} +1 -1
  12. data/ext/ffi_c/Invoker.c +148 -192
  13. data/ext/ffi_c/LastError.c +135 -0
  14. data/ext/ffi_c/LastError.h +18 -0
  15. data/ext/ffi_c/MemoryPointer.c +26 -19
  16. data/ext/ffi_c/MemoryPointer.h +3 -3
  17. data/ext/ffi_c/NullPointer.c +49 -47
  18. data/ext/ffi_c/Platform.c +9 -10
  19. data/ext/ffi_c/Platform.h +1 -1
  20. data/ext/ffi_c/Pointer.c +52 -21
  21. data/ext/ffi_c/Pointer.h +8 -6
  22. data/ext/ffi_c/Struct.c +70 -61
  23. data/ext/ffi_c/Struct.h +2 -2
  24. data/ext/ffi_c/Type.c +230 -0
  25. data/ext/ffi_c/Type.h +28 -0
  26. data/ext/ffi_c/Types.c +47 -6
  27. data/ext/ffi_c/Types.h +8 -2
  28. data/ext/ffi_c/endian.h +40 -0
  29. data/ext/ffi_c/extconf.rb +6 -5
  30. data/ext/ffi_c/ffi.c +20 -43
  31. data/ext/ffi_c/libffi.bsd.mk +34 -0
  32. data/ext/ffi_c/libffi.darwin.mk +30 -10
  33. data/ext/ffi_c/libffi.gnu.mk +29 -0
  34. data/ext/ffi_c/libffi.mk +4 -2
  35. data/ext/ffi_c/rbffi.h +6 -8
  36. data/lib/ffi.rb +10 -1
  37. data/lib/ffi/autopointer.rb +1 -1
  38. data/lib/ffi/enum.rb +78 -0
  39. data/lib/ffi/ffi.rb +5 -6
  40. data/lib/ffi/io.rb +15 -1
  41. data/lib/ffi/library.rb +78 -17
  42. data/lib/ffi/pointer.rb +2 -2
  43. data/lib/ffi/struct.rb +68 -14
  44. data/lib/ffi/types.rb +6 -3
  45. data/lib/ffi/variadic.rb +2 -2
  46. data/spec/ffi/bool_spec.rb +24 -0
  47. data/spec/ffi/callback_spec.rb +217 -17
  48. data/spec/ffi/enum_spec.rb +164 -0
  49. data/spec/ffi/managed_struct_spec.rb +6 -1
  50. data/spec/ffi/number_spec.rb +30 -0
  51. data/spec/ffi/pointer_spec.rb +33 -8
  52. data/spec/ffi/rbx/memory_pointer_spec.rb +0 -6
  53. data/spec/ffi/spec_helper.rb +5 -1
  54. data/spec/ffi/string_spec.rb +65 -4
  55. data/spec/ffi/struct_callback_spec.rb +41 -0
  56. data/spec/ffi/struct_initialize_spec.rb +30 -0
  57. data/spec/ffi/struct_spec.rb +19 -20
  58. metadata +29 -52
  59. data/ext/ffi_c/ffi.mk +0 -23
@@ -1,4 +1,5 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
2
+ require 'java' if RUBY_PLATFORM =~ /java/
2
3
 
3
4
  describe "Managed Struct" do
4
5
  include FFI
@@ -33,7 +34,11 @@ describe "Managed Struct" do
33
34
  loop = 5
34
35
  while loop > 0 && @@count < count
35
36
  loop -= 1
36
- GC.start
37
+ if RUBY_PLATFORM =~ /java/
38
+ java.lang.System.gc
39
+ else
40
+ GC.start
41
+ end
37
42
  sleep 0.05 if @@count < count
38
43
  end
39
44
  end
@@ -20,6 +20,36 @@ describe "Function with primitive integer arguments" do
20
20
  attach_function :set_double, [ :double ], :void
21
21
  attach_function :get_double, [ ], :double
22
22
  end
23
+ it "int8.size" do
24
+ FFI::TYPE_INT8.size.should == 1
25
+ end
26
+ it "uint8.size" do
27
+ FFI::TYPE_UINT8.size.should == 1
28
+ end
29
+ it "int16.size" do
30
+ FFI::TYPE_INT16.size.should == 2
31
+ end
32
+ it "uint16.size" do
33
+ FFI::TYPE_UINT16.size.should == 2
34
+ end
35
+ it "int32.size" do
36
+ FFI::TYPE_INT32.size.should == 4
37
+ end
38
+ it "uint32.size" do
39
+ FFI::TYPE_UINT32.size.should == 4
40
+ end
41
+ it "int64.size" do
42
+ FFI::TYPE_INT64.size.should == 8
43
+ end
44
+ it "uint64.size" do
45
+ FFI::TYPE_UINT64.size.should == 8
46
+ end
47
+ it "float.size" do
48
+ FFI::TYPE_FLOAT32.size.should == 4
49
+ end
50
+ it "double.size" do
51
+ FFI::TYPE_FLOAT64.size.should == 8
52
+ end
23
53
  [ 0, 127, -128, -1 ].each do |i|
24
54
  it ":char call(:char (#{i}))" do
25
55
  LibTest.ret_s8(i).should == i
@@ -1,5 +1,7 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
2
2
  require 'delegate'
3
+ require 'java' if RUBY_PLATFORM =~ /java/
4
+
3
5
  module LibTest
4
6
  attach_function :ptr_ret_int32_t, [ :pointer, :int ], :int
5
7
  attach_function :ptr_from_address, [ FFI::Platform::ADDRESS_SIZE == 32 ? :uint : :ulong_long ], :pointer
@@ -25,7 +27,6 @@ describe "Pointer" do
25
27
  end
26
28
  class PointerDelegate < DelegateClass(FFI::Pointer)
27
29
  def initialize(ptr)
28
- super
29
30
  @ptr = ptr
30
31
  end
31
32
  def to_ptr
@@ -84,7 +85,22 @@ describe "Pointer" do
84
85
  array[j].address.should == address
85
86
  end
86
87
  end
88
+
89
+ end
87
90
 
91
+ describe 'NULL' do
92
+ it 'should be obtained using Pointer::NULL constant' do
93
+ null_ptr = FFI::Pointer::NULL
94
+ null_ptr.null?.should be_true
95
+ end
96
+ it 'should be obtained passing address 0 to constructor' do
97
+ FFI::Pointer.new(0).null?.should be_true
98
+ end
99
+ it 'should raise an error when attempting read/write operations on it' do
100
+ null_ptr = FFI::Pointer::NULL
101
+ lambda { null_ptr.read_int }.should raise_error(FFI::NullPointerError)
102
+ lambda { null_ptr.write_int(0xff1) }.should raise_error(FFI::NullPointerError)
103
+ end
88
104
  end
89
105
 
90
106
  end
@@ -106,7 +122,11 @@ describe "AutoPointer" do
106
122
  loop = 5
107
123
  while @@count < count && loop > 0
108
124
  loop -= 1
109
- GC.start
125
+ if RUBY_PLATFORM =~ /java/
126
+ java.lang.System.gc
127
+ else
128
+ GC.start
129
+ end
110
130
  sleep 0.05 unless @@count == count
111
131
  end
112
132
  @@count = 0
@@ -115,15 +135,17 @@ describe "AutoPointer" do
115
135
  self.method(:release).to_proc
116
136
  end
117
137
  end
118
-
138
+ class AutoPointerSubclass < FFI::AutoPointer
139
+ def self.release(ptr); end
140
+ end
119
141
  it "cleanup via default release method" do
120
- FFI::AutoPointer.should_receive(:release).at_least(loop_count-wiggle_room).times
142
+ AutoPointerSubclass.should_receive(:release).at_least(loop_count-wiggle_room).times
121
143
  AutoPointerTestHelper.reset
122
144
  loop_count.times do
123
145
  # note that if we called
124
146
  # AutoPointerTestHelper.method(:release).to_proc inline, we'd
125
147
  # have a reference to the pointer and it would never get GC'd.
126
- ap = FFI::AutoPointer.new(LibTest.ptr_from_address(magic))
148
+ ap = AutoPointerSubclass.new(LibTest.ptr_from_address(magic))
127
149
  end
128
150
  AutoPointerTestHelper.gc_everything loop_count
129
151
  end
@@ -157,14 +179,17 @@ describe "AutoPointer" do
157
179
  end
158
180
  end
159
181
  describe "AutoPointer#new" do
182
+ class AutoPointerSubclass < FFI::AutoPointer
183
+ def self.release(ptr); end
184
+ end
160
185
  it "MemoryPointer argument raises ArgumentError" do
161
- lambda { FFI::AutoPointer.new(FFI::MemoryPointer.new(:int))}.should raise_error(ArgumentError)
186
+ lambda { FFI::AutoPointer.new(FFI::MemoryPointer.new(:int))}.should raise_error(::TypeError)
162
187
  end
163
188
  it "AutoPointer argument raises ArgumentError" do
164
- lambda { FFI::AutoPointer.new(FFI::AutoPointer.new(LibTest.ptr_from_address(0))) }.should raise_error(ArgumentError)
189
+ lambda { AutoPointerSubclass.new(AutoPointerSubclass.new(LibTest.ptr_from_address(0))) }.should raise_error(::TypeError)
165
190
  end
166
191
  it "Buffer argument raises ArgumentError" do
167
- lambda { FFI::AutoPointer.new(FFI::Buffer.new(:int))}.should raise_error(ArgumentError)
192
+ lambda { FFI::AutoPointer.new(FFI::Buffer.new(:int))}.should raise_error(::TypeError)
168
193
  end
169
194
 
170
195
  end
@@ -18,12 +18,6 @@ describe "MemoryPointer" do
18
18
  m.read_string.should == "FFI is Awesome"
19
19
  end
20
20
 
21
- it "reads back a string from an Array of ints" do
22
- m = FFI::MemoryPointer.new(:int, 4)
23
- m.write_array_of_int([541673030, 1092645737, 1869833591, 538994029])
24
- m.read_string(16).should == "FFI is Awesome "
25
- end
26
-
27
21
  it "makes a pointer for a certain number of bytes" do
28
22
  m = FFI::MemoryPointer.new(8)
29
23
  m.write_array_of_int([1,2])
@@ -1,7 +1,11 @@
1
1
  require 'rubygems'
2
+ require 'rbconfig'
2
3
  require 'spec'
3
4
 
4
- $:.unshift File.join(File.dirname(__FILE__), "..", "..", "lib"), File.join(File.dirname(__FILE__), "..", "..", "build", RUBY_VERSION) if ENV["MRI_FFI"]
5
+ if ENV["MRI_FFI"]
6
+ $:.unshift File.join(File.dirname(__FILE__), "..", "..", "lib"),
7
+ File.join(File.dirname(__FILE__), "..", "..", "build", "#{Config::CONFIG['host_cpu''arch']}", "ffi_c", RUBY_VERSION)
8
+ end
5
9
  require "ffi"
6
10
 
7
11
  module TestLibrary
@@ -1,12 +1,13 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
2
2
  describe "String tests" do
3
3
  include FFI
4
- module LibTest
4
+ module StrLibTest
5
5
  extend FFI::Library
6
6
  ffi_lib TestLibrary::PATH
7
7
  attach_function :ptr_ret_pointer, [ :pointer, :int], :string
8
8
  attach_function :string_equals, [ :string, :string ], :int
9
9
  attach_function :string_dummy, [ :string ], :void
10
+ attach_function :string_null, [ ], :string
10
11
  end
11
12
  it "MemoryPointer#get_string returns a tainted string" do
12
13
  mp = MemoryPointer.new 1024
@@ -19,13 +20,13 @@ describe "String tests" do
19
20
  sp = MemoryPointer.new 1024
20
21
  sp.put_string(0, "test")
21
22
  mp.put_pointer(0, sp)
22
- str = LibTest.ptr_ret_pointer(mp, 0)
23
+ str = StrLibTest.ptr_ret_pointer(mp, 0)
23
24
  str.should == "test"
24
25
  str.tainted?.should == true
25
26
  end
26
27
  it "Poison null byte raises error" do
27
28
  s = "123\0abc"
28
- lambda { LibTest.string_equals(s, s) }.should raise_error
29
+ lambda { StrLibTest.string_equals(s, s) }.should raise_error
29
30
  end
30
31
  it "Tainted String parameter should throw a SecurityError" do
31
32
  $SAFE = 1
@@ -37,6 +38,66 @@ describe "String tests" do
37
38
  end
38
39
  end if false
39
40
  it "casts nil as NULL pointer" do
40
- LibTest.string_dummy(nil)
41
+ StrLibTest.string_dummy(nil)
42
+ end
43
+ it "return nil for NULL char*" do
44
+ StrLibTest.string_null.should == nil
45
+ end
46
+ it "reads an array of strings until encountering a NULL pointer" do
47
+ strings = ["foo", "bar", "baz", "testing", "ffi"]
48
+ ptrary = MemoryPointer.new(:pointer, 6)
49
+ ary = strings.inject([]) do |a, str|
50
+ f = MemoryPointer.new(1024)
51
+ f.put_string(0, str)
52
+ a << f
53
+ end
54
+ ary.insert(3, nil)
55
+ ptrary.write_array_of_pointer(ary)
56
+ ptrary.get_array_of_string(0).should == ["foo", "bar", "baz"]
57
+ end
58
+ it "reads an array of strings of the size specified, substituting nil when a pointer is NULL" do
59
+ strings = ["foo", "bar", "baz", "testing", "ffi"]
60
+ ptrary = MemoryPointer.new(:pointer, 6)
61
+ ary = strings.inject([]) do |a, str|
62
+ f = MemoryPointer.new(1024)
63
+ f.put_string(0, str)
64
+ a << f
65
+ end
66
+ ary.insert(2, nil)
67
+ ptrary.write_array_of_pointer(ary)
68
+ ptrary.get_array_of_string(0, 4).should == ["foo", "bar", nil, "baz"]
69
+ end
70
+ it "reads an array of strings, taking a memory offset parameter" do
71
+ strings = ["foo", "bar", "baz", "testing", "ffi"]
72
+ ptrary = MemoryPointer.new(:pointer, 5)
73
+ ary = strings.inject([]) do |a, str|
74
+ f = MemoryPointer.new(1024)
75
+ f.put_string(0, str)
76
+ a << f
77
+ end
78
+ ptrary.write_array_of_pointer(ary)
79
+ ptrary.get_array_of_string(2 * FFI.type_size(:pointer), 3).should == ["baz", "testing", "ffi"]
80
+ end
81
+ it "raises an IndexError when trying to read an array of strings out of bounds" do
82
+ strings = ["foo", "bar", "baz", "testing", "ffi"]
83
+ ptrary = MemoryPointer.new(:pointer, 5)
84
+ ary = strings.inject([]) do |a, str|
85
+ f = MemoryPointer.new(1024)
86
+ f.put_string(0, str)
87
+ a << f
88
+ end
89
+ ptrary.write_array_of_pointer(ary)
90
+ lambda { ptrary.get_array_of_string(0, 6) }.should raise_error
91
+ end
92
+ it "raises an IndexError when trying to read an array of strings using a negative offset" do
93
+ strings = ["foo", "bar", "baz", "testing", "ffi"]
94
+ ptrary = MemoryPointer.new(:pointer, 5)
95
+ ary = strings.inject([]) do |a, str|
96
+ f = MemoryPointer.new(1024)
97
+ f.put_string(0, str)
98
+ a << f
99
+ end
100
+ ptrary.write_array_of_pointer(ary)
101
+ lambda { ptrary.get_array_of_string(-1) }.should raise_error
41
102
  end
42
103
  end
@@ -0,0 +1,41 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
2
+
3
+ describe FFI::Struct, ' with inline callback functions' do
4
+ it 'should be able to define inline callback field' do
5
+ module CallbackMember
6
+ extend FFI::Library
7
+ ffi_lib TestLibrary::PATH
8
+ class TestStruct < FFI::Struct
9
+ layout \
10
+ :add, callback([ :int, :int ], :int),
11
+ :sub, callback([ :int, :int ], :int)
12
+ end
13
+ attach_function :struct_call_add_cb, [TestStruct, :int, :int], :int
14
+ attach_function :struct_call_sub_cb, [TestStruct, :int, :int], :int
15
+ end
16
+ end
17
+ it 'should take methods as callbacks' do
18
+ module CallbackMember
19
+ extend FFI::Library
20
+ ffi_lib TestLibrary::PATH
21
+ class TestStruct < FFI::Struct
22
+ layout \
23
+ :add, callback([ :int, :int ], :int),
24
+ :sub, callback([ :int, :int ], :int)
25
+ end
26
+ attach_function :struct_call_add_cb, [TestStruct, :int, :int], :int
27
+ attach_function :struct_call_sub_cb, [TestStruct, :int, :int], :int
28
+ end
29
+ module StructCallbacks
30
+ def self.add a, b
31
+ a+b
32
+ end
33
+ end
34
+
35
+ ts = CallbackMember::TestStruct.new
36
+ ts[:add] = StructCallbacks.method(:add)
37
+
38
+ CallbackMember.struct_call_add_cb(ts, 1, 2).should == 3
39
+ end
40
+ end
41
+
@@ -0,0 +1,30 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
2
+
3
+ describe FFI::Struct, ' with an initialize function' do
4
+ it "should call the initialize function" do
5
+ class StructWithInitialize < FFI::Struct
6
+ layout :string, :string
7
+ attr_accessor :magic
8
+ def initialize
9
+ super
10
+ self.magic = 42
11
+ end
12
+ end
13
+ StructWithInitialize.new.magic.should == 42
14
+ end
15
+ end
16
+
17
+ describe FFI::ManagedStruct, ' with an initialize function' do
18
+ it "should call the initialize function" do
19
+ class ManagedStructWithInitialize < FFI::ManagedStruct
20
+ layout :string, :string
21
+ attr_accessor :magic
22
+ def initialize
23
+ super MemoryPointer.new(:pointer).put_int(0, 0x1234).get_pointer(0)
24
+ self.magic = 42
25
+ end
26
+ def self.release;end
27
+ end
28
+ ManagedStructWithInitialize.new.magic.should == 42
29
+ end
30
+ end
@@ -1,6 +1,5 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
2
2
  describe "Struct tests" do
3
- include FFI
4
3
  StructTypes = {
5
4
  's8' => :char,
6
5
  's16' => :short,
@@ -29,54 +28,54 @@ describe "Struct tests" do
29
28
  end
30
29
  it "Struct#[:pointer]" do
31
30
  magic = 0x12345678
32
- mp = MemoryPointer.new :long
31
+ mp = FFI::MemoryPointer.new :long
33
32
  mp.put_long(0, magic)
34
- smp = MemoryPointer.new :pointer
33
+ smp = FFI::MemoryPointer.new :pointer
35
34
  smp.put_pointer(0, mp)
36
35
  s = PointerMember.new smp
37
36
  s[:pointer].should == mp
38
37
  end
39
38
  it "Struct#[:pointer].nil? for NULL value" do
40
39
  magic = 0x12345678
41
- mp = MemoryPointer.new :long
40
+ mp = FFI::MemoryPointer.new :long
42
41
  mp.put_long(0, magic)
43
- smp = MemoryPointer.new :pointer
42
+ smp = FFI::MemoryPointer.new :pointer
44
43
  smp.put_pointer(0, nil)
45
44
  s = PointerMember.new smp
46
45
  s[:pointer].null?.should == true
47
46
  end
48
47
  it "Struct#[:pointer]=" do
49
48
  magic = 0x12345678
50
- mp = MemoryPointer.new :long
49
+ mp = FFI::MemoryPointer.new :long
51
50
  mp.put_long(0, magic)
52
- smp = MemoryPointer.new :pointer
51
+ smp = FFI::MemoryPointer.new :pointer
53
52
  s = PointerMember.new smp
54
53
  s[:pointer] = mp
55
54
  smp.get_pointer(0).should == mp
56
55
  end
57
56
  it "Struct#[:pointer]=struct" do
58
57
  magic = 0x12345678
59
- smp = MemoryPointer.new :pointer
58
+ smp = FFI::MemoryPointer.new :pointer
60
59
  s = PointerMember.new smp
61
60
  lambda { s[:pointer] = s }.should_not raise_error
62
61
  end
63
62
  it "Struct#[:pointer]=nil" do
64
- smp = MemoryPointer.new :pointer
63
+ smp = FFI::MemoryPointer.new :pointer
65
64
  s = PointerMember.new smp
66
65
  s[:pointer] = nil
67
66
  smp.get_pointer(0).null?.should == true
68
67
  end
69
68
  it "Struct#[:string]" do
70
69
  magic = "test"
71
- mp = MemoryPointer.new 1024
70
+ mp = FFI::MemoryPointer.new 1024
72
71
  mp.put_string(0, magic)
73
- smp = MemoryPointer.new :pointer
72
+ smp = FFI::MemoryPointer.new :pointer
74
73
  smp.put_pointer(0, mp)
75
74
  s = StringMember.new smp
76
75
  s[:string].should == magic
77
76
  end
78
77
  it "Struct#[:string].nil? for NULL value" do
79
- smp = MemoryPointer.new :pointer
78
+ smp = FFI::MemoryPointer.new :pointer
80
79
  smp.put_pointer(0, nil)
81
80
  s = StringMember.new smp
82
81
  s[:string].nil?.should == true
@@ -85,9 +84,9 @@ describe "Struct tests" do
85
84
  class PairLayout < FFI::Struct
86
85
  layout :a, :int, :b, :long_long
87
86
  end
88
- ll_off = (FFI::Platform::ADDRESS_SIZE == 32 ? 4 : 8)
87
+ ll_off = (FFI::TYPE_UINT64.alignment == 4 ? 4 : 8)
89
88
  PairLayout.size.should == (ll_off + 8)
90
- mp = MemoryPointer.new(PairLayout.size)
89
+ mp = FFI::MemoryPointer.new(PairLayout.size)
91
90
  s = PairLayout.new mp
92
91
  s[:a] = 0x12345678
93
92
  mp.get_int(0).should == 0x12345678
@@ -98,8 +97,8 @@ describe "Struct tests" do
98
97
  class PairLayout < FFI::Struct
99
98
  layout :a, :int, 0, :b, :long_long, 4
100
99
  end
101
- PairLayout.size.should == (FFI::Platform::ADDRESS_SIZE == 32 ? 12 : 16)
102
- mp = MemoryPointer.new(PairLayout.size)
100
+ PairLayout.size.should == (FFI::TYPE_UINT64.alignment == 4 ? 12 : 16)
101
+ mp = FFI::MemoryPointer.new(PairLayout.size)
103
102
  s = PairLayout.new mp
104
103
  s[:a] = 0x12345678
105
104
  mp.get_int(0).should == 0x12345678
@@ -110,8 +109,8 @@ describe "Struct tests" do
110
109
  class MixedLayout < FFI::Struct
111
110
  layout :a, :int, :b, :long_long, 4
112
111
  end
113
- MixedLayout.size.should == (FFI::Platform::ADDRESS_SIZE == 32 ? 12 : 16)
114
- mp = MemoryPointer.new(MixedLayout.size)
112
+ MixedLayout.size.should == (FFI::TYPE_UINT64.alignment == 4 ? 12 : 16)
113
+ mp = FFI::MemoryPointer.new(MixedLayout.size)
115
114
  s = MixedLayout.new mp
116
115
  s[:a] = 0x12345678
117
116
  mp.get_int(0).should == 0x12345678
@@ -124,9 +123,9 @@ describe "Struct tests" do
124
123
  class HashLayout < FFI::Struct
125
124
  layout :a => :int, :b => :long_long
126
125
  end
127
- ll_off = (FFI::Platform::ADDRESS_SIZE == 32 ? 4 : 8)
126
+ ll_off = (FFI::TYPE_UINT64.alignment == 4? 4 : 8)
128
127
  HashLayout.size.should == (ll_off + 8)
129
- mp = MemoryPointer.new(HashLayout.size)
128
+ mp = FFI::MemoryPointer.new(HashLayout.size)
130
129
  s = HashLayout.new mp
131
130
  s[:a] = 0x12345678
132
131
  mp.get_int(0).should == 0x12345678