ffi 0.5.4-x86-mswin32 → 0.6.3-x86-mswin32
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.
- data/History.txt +102 -0
- data/LICENSE +1 -27
- data/Rakefile +4 -12
- data/ext/ffi_c/AbstractMemory.c +6 -8
- data/ext/ffi_c/AbstractMemory.h +23 -21
- data/ext/ffi_c/AutoPointer.c +0 -1
- data/ext/ffi_c/Buffer.c +23 -8
- data/ext/ffi_c/Call.c +31 -3
- data/ext/ffi_c/Call.h +5 -1
- data/ext/ffi_c/DynamicLibrary.c +0 -1
- data/ext/ffi_c/Function.c +22 -4
- data/ext/ffi_c/MemoryPointer.c +2 -3
- data/ext/ffi_c/Pointer.c +23 -9
- data/ext/ffi_c/Struct.c +227 -79
- data/ext/ffi_c/Struct.h +16 -7
- data/ext/ffi_c/StructLayout.c +92 -55
- data/ext/ffi_c/Type.c +5 -22
- data/ext/ffi_c/Type.h +1 -1
- data/ext/ffi_c/Types.c +9 -3
- data/ext/ffi_c/Types.h +2 -0
- data/ext/ffi_c/extconf.rb +11 -7
- data/ext/ffi_c/libffi.gnu.mk +1 -1
- data/ext/ffi_c/libffi.mk +1 -1
- data/ext/ffi_c/libffi/ChangeLog +900 -84
- data/ext/ffi_c/libffi/ChangeLog.libffi +311 -0
- data/ext/ffi_c/libffi/LICENSE +1 -1
- data/ext/ffi_c/libffi/Makefile.am +14 -4
- data/ext/ffi_c/libffi/Makefile.in +362 -211
- data/ext/ffi_c/libffi/README +70 -92
- data/ext/ffi_c/libffi/aclocal.m4 +6068 -4586
- data/ext/ffi_c/libffi/config.guess +125 -143
- data/ext/ffi_c/libffi/config.sub +103 -27
- data/ext/ffi_c/libffi/configure +11340 -18473
- data/ext/ffi_c/libffi/configure.ac +43 -4
- data/ext/ffi_c/libffi/doc/libffi.info +15 -15
- data/ext/ffi_c/libffi/doc/libffi.texi +1 -1
- data/ext/ffi_c/libffi/doc/stamp-vti +4 -4
- data/ext/ffi_c/libffi/doc/version.texi +4 -4
- data/ext/ffi_c/libffi/fficonfig.h.in +24 -3
- data/ext/ffi_c/libffi/include/Makefile.am +1 -1
- data/ext/ffi_c/libffi/include/Makefile.in +97 -50
- data/ext/ffi_c/libffi/include/ffi.h.in +8 -2
- data/ext/ffi_c/libffi/include/ffi_common.h +24 -0
- data/ext/ffi_c/libffi/libtool-version +1 -1
- data/ext/ffi_c/libffi/ltmain.sh +7346 -5870
- data/ext/ffi_c/libffi/m4/libtool.m4 +7360 -0
- data/ext/ffi_c/libffi/m4/ltoptions.m4 +368 -0
- data/ext/ffi_c/libffi/m4/ltsugar.m4 +123 -0
- data/ext/ffi_c/libffi/m4/ltversion.m4 +23 -0
- data/ext/ffi_c/libffi/m4/lt~obsolete.m4 +92 -0
- data/ext/ffi_c/libffi/man/Makefile.in +115 -62
- data/ext/ffi_c/libffi/man/ffi_call.3 +3 -3
- data/ext/ffi_c/libffi/missing +15 -8
- data/ext/ffi_c/libffi/src/arm/sysv.S +15 -8
- data/ext/ffi_c/libffi/src/avr32/ffi.c +421 -0
- data/ext/ffi_c/libffi/src/avr32/ffitarget.h +50 -0
- data/ext/ffi_c/libffi/src/avr32/sysv.S +208 -0
- data/ext/ffi_c/libffi/src/closures.c +47 -10
- data/ext/ffi_c/libffi/src/frv/ffi.c +1 -1
- data/ext/ffi_c/libffi/src/java_raw_api.c +0 -3
- data/ext/ffi_c/libffi/src/mips/ffi.c +135 -32
- data/ext/ffi_c/libffi/src/mips/ffitarget.h +37 -4
- data/ext/ffi_c/libffi/src/mips/n32.S +67 -10
- data/ext/ffi_c/libffi/src/mips/o32.S +8 -8
- data/ext/ffi_c/libffi/src/pa/ffi.c +7 -0
- data/ext/ffi_c/libffi/src/powerpc/aix.S +163 -64
- data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +308 -112
- data/ext/ffi_c/libffi/src/powerpc/ffi.c +20 -7
- data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +208 -80
- data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +11 -3
- data/ext/ffi_c/libffi/src/powerpc/sysv.S +12 -23
- data/ext/ffi_c/libffi/src/s390/sysv.S +1 -1
- data/ext/ffi_c/libffi/src/sh/sysv.S +9 -9
- data/ext/ffi_c/libffi/src/sh64/ffi.c +37 -22
- data/ext/ffi_c/libffi/src/sh64/sysv.S +23 -14
- data/ext/ffi_c/libffi/src/sparc/ffi.c +21 -6
- data/ext/ffi_c/libffi/src/sparc/v8.S +55 -14
- data/ext/ffi_c/libffi/src/x86/darwin.S +10 -9
- data/ext/ffi_c/libffi/src/x86/ffi.c +293 -86
- data/ext/ffi_c/libffi/src/x86/ffi64.c +73 -19
- data/ext/ffi_c/libffi/src/x86/ffitarget.h +30 -0
- data/ext/ffi_c/libffi/src/x86/sysv.S +21 -4
- data/ext/ffi_c/libffi/src/x86/unix64.S +8 -4
- data/ext/ffi_c/libffi/src/x86/win32.S +633 -147
- data/ext/ffi_c/libffi/src/x86/win64.S +460 -0
- data/ext/ffi_c/libffi/testsuite/Makefile.am +63 -54
- data/ext/ffi_c/libffi/testsuite/Makefile.in +112 -77
- data/ext/ffi_c/libffi/testsuite/lib/libffi-dg.exp +12 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn0.c +7 -15
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn1.c +7 -15
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn2.c +7 -15
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn3.c +7 -15
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn4.c +7 -15
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn5.c +7 -14
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn6.c +7 -15
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_loc_fn0.c +95 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_stdcall.c +6 -14
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_12byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_16byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_18byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_19byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_1_1byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte1.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_24byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_2byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3_1byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte1.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte2.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4_1byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5_1_byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_64byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6_1_byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7_1_byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_8byte.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte1.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte2.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_double.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_float.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split.c +134 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c +117 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_pointer.c +11 -17
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint16.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint32.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint64.c +7 -15
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint16.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint32.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint64.c +7 -15
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_dbls_struct.c +66 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_double.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_double_va.c +57 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_float.c +4 -13
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble.c +105 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble_va.c +57 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_schar.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshort.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshortchar.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_uchar.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushort.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushortchar.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer.c +74 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer_stack.c +140 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_schar.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_sint.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_sshort.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uchar.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uint.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulonglong.c +8 -16
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ushort.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_abi.c +37 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_typedef.c +25 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +31 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/float2.c +2 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/huge_struct.c +342 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct1.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct10.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct2.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct3.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct4.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct5.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct6.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct7.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct8.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct9.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/problem1.c +4 -12
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_ldl.c +1 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll1.c +1 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/stret_large.c +145 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/stret_large2.c +148 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium.c +124 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium2.c +124 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/testclosure.c +70 -0
- data/ext/ffi_c/libffi/testsuite/libffi.special/ffitestcxx.h +10 -0
- data/ext/ffi_c/libffi/testsuite/libffi.special/special.exp +4 -5
- data/ext/ffi_c/libffi/testsuite/libffi.special/unwindtest.cc +17 -16
- data/ext/ffi_c/libffi/texinfo.tex +155 -427
- data/gen/Rakefile +4 -2
- data/lib/1.8/ffi_c.so +0 -0
- data/lib/1.9/ffi_c.so +0 -0
- data/lib/ffi/autopointer.rb +79 -20
- data/lib/ffi/callback.rb +4 -10
- data/lib/ffi/enum.rb +28 -0
- data/lib/ffi/ffi.rb +1 -0
- data/lib/ffi/io.rb +28 -0
- data/lib/ffi/library.rb +237 -182
- data/lib/ffi/memorypointer.rb +28 -62
- data/lib/ffi/platform.rb +27 -0
- data/lib/ffi/pointer.rb +28 -0
- data/lib/ffi/struct.rb +55 -1
- data/lib/ffi/types.rb +29 -0
- data/lib/ffi/variadic.rb +29 -0
- data/spec/ffi/library_spec.rb +31 -5
- data/spec/ffi/rbx/attach_function_spec.rb +2 -1
- data/spec/ffi/rbx/memory_pointer_spec.rb +2 -1
- data/spec/ffi/spec_helper.rb +5 -1
- data/spec/ffi/struct_spec.rb +82 -0
- data/tasks/ann.rake +80 -0
- data/tasks/extension.rake +25 -0
- data/tasks/gem.rake +200 -0
- data/tasks/git.rake +41 -0
- data/tasks/notes.rake +27 -0
- data/tasks/post_load.rake +34 -0
- data/tasks/rdoc.rake +50 -0
- data/tasks/rubyforge.rake +55 -0
- data/tasks/setup.rb +300 -0
- data/tasks/spec.rake +54 -0
- data/tasks/svn.rake +47 -0
- data/tasks/test.rake +40 -0
- metadata +312 -279
- data/ext/ffi_c/libffi/TODO +0 -1
- data/ext/ffi_c/libffi/ltcf-c.sh +0 -861
- data/ext/ffi_c/libffi/ltcf-cxx.sh +0 -1069
- data/ext/ffi_c/libffi/ltcf-gcj.sh +0 -700
- data/ext/ffi_c/libffi/ltconfig +0 -2862
- data/ext/ffi_c/libffi/mkinstalldirs +0 -158
data/lib/ffi/memorypointer.rb
CHANGED
@@ -1,73 +1,39 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (C) 2008, 2009 Wayne Meissner
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
9
|
+
# list of conditions and the following disclaimer.
|
10
|
+
# * Redistributions in binary form must reproduce the above copyright notice
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
# * Neither the name of the Evan Phoenix nor the names of its contributors
|
14
|
+
# may be used to endorse or promote products derived from this software
|
15
|
+
# without specific prior written permission.
|
16
|
+
#
|
17
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
18
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
19
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
21
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
22
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
23
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
24
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
25
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
26
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27
|
+
|
1
28
|
require 'ffi/pointer'
|
2
29
|
module FFI
|
3
30
|
class MemoryPointer
|
4
|
-
|
5
|
-
# MemoryPointer.new(num) => MemoryPointer instance of <i>num</i> bytes
|
6
|
-
# MemoryPointer.new(sym) => MemoryPointer instance with number
|
7
|
-
# of bytes need by FFI type <i>sym</i>
|
8
|
-
# MemoryPointer.new(obj) => MemoryPointer instance with number
|
9
|
-
# of <i>obj.size</i> bytes
|
10
|
-
# MemoryPointer.new(sym, count) => MemoryPointer instance with number
|
11
|
-
# of bytes need by length-<i>count</i> array
|
12
|
-
# of FFI type <i>sym</i>
|
13
|
-
# MemoryPointer.new(obj, count) => MemoryPointer instance with number
|
14
|
-
# of bytes need by length-<i>count</i> array
|
15
|
-
# of <i>obj.size</i> bytes
|
16
|
-
# MemoryPointer.new(arg) { |p| ... }
|
17
|
-
#
|
18
|
-
# Both forms create a MemoryPointer instance. The number of bytes to
|
19
|
-
# allocate is either specified directly or by passing an FFI type, which
|
20
|
-
# specifies the number of bytes needed for that type.
|
21
|
-
#
|
22
|
-
# The form without a block returns the MemoryPointer instance. The form
|
23
|
-
# with a block yields the MemoryPointer instance and frees the memory
|
24
|
-
# when the block returns. The value returned is the value of the block.
|
25
|
-
|
26
|
-
# def self.new(type, count=nil, clear=true)
|
27
|
-
# size = if type.kind_of? Fixnum
|
28
|
-
# type
|
29
|
-
# elsif type.kind_of? Symbol
|
30
|
-
# FFI.type_size(type)
|
31
|
-
# else
|
32
|
-
# type.size
|
33
|
-
# end
|
34
|
-
# ptr = self.__allocate(size, count, clear)
|
35
|
-
# ptr.type_size = size
|
36
|
-
# if block_given?
|
37
|
-
# begin
|
38
|
-
# value = yield ptr
|
39
|
-
# ensure
|
40
|
-
# ptr.free
|
41
|
-
# end
|
42
|
-
# value
|
43
|
-
# else
|
44
|
-
# ptr
|
45
|
-
# end
|
46
|
-
# end
|
31
|
+
|
47
32
|
def self.from_string(s)
|
48
33
|
ptr = self.new(s.length + 1, 1, false)
|
49
34
|
ptr.put_string(0, s)
|
50
35
|
ptr
|
51
36
|
end
|
52
|
-
# Indicates how many bytes the type that the pointer is cast as uses.
|
53
|
-
# attr_accessor :type_size
|
54
37
|
|
55
|
-
# Access the MemoryPointer like a C array, accessing the +which+ number
|
56
|
-
# element in memory. The position of the element is calculate from
|
57
|
-
# +@type_size+ and +which+. A new MemoryPointer object is returned, which
|
58
|
-
# points to the address of the element.
|
59
|
-
#
|
60
|
-
# Example:
|
61
|
-
# ptr = MemoryPointer.new(:int, 20)
|
62
|
-
# new_ptr = ptr[9]
|
63
|
-
#
|
64
|
-
# c-equiv:
|
65
|
-
# int *ptr = (int*)malloc(sizeof(int) * 20);
|
66
|
-
# int *new_ptr;
|
67
|
-
# new_ptr = &ptr[9];
|
68
|
-
#
|
69
|
-
# def [](which)
|
70
|
-
# self + (which * type_size)
|
71
|
-
# end
|
72
38
|
end
|
73
39
|
end
|
data/lib/ffi/platform.rb
CHANGED
@@ -1,3 +1,30 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (C) 2008, 2009 Wayne Meissner
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
9
|
+
# list of conditions and the following disclaimer.
|
10
|
+
# * Redistributions in binary form must reproduce the above copyright notice
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
# * Neither the name of the Evan Phoenix nor the names of its contributors
|
14
|
+
# may be used to endorse or promote products derived from this software
|
15
|
+
# without specific prior written permission.
|
16
|
+
#
|
17
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
18
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
19
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
21
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
22
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
23
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
24
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
25
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
26
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27
|
+
|
1
28
|
require 'rbconfig'
|
2
29
|
module FFI
|
3
30
|
class PlatformError < FFI::NativeError; end
|
data/lib/ffi/pointer.rb
CHANGED
@@ -1,3 +1,31 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (C) 2008, 2009 Wayne Meissner
|
3
|
+
# Copyright (c) 2007, 2008 Evan Phoenix
|
4
|
+
# All rights reserved.
|
5
|
+
#
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
7
|
+
# modification, are permitted provided that the following conditions are met:
|
8
|
+
#
|
9
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
10
|
+
# list of conditions and the following disclaimer.
|
11
|
+
# * Redistributions in binary form must reproduce the above copyright notice
|
12
|
+
# this list of conditions and the following disclaimer in the documentation
|
13
|
+
# and/or other materials provided with the distribution.
|
14
|
+
# * Neither the name of the Evan Phoenix nor the names of its contributors
|
15
|
+
# may be used to endorse or promote products derived from this software
|
16
|
+
# without specific prior written permission.
|
17
|
+
#
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
21
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
22
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
26
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
|
1
29
|
require 'ffi/platform'
|
2
30
|
module FFI
|
3
31
|
class Pointer
|
data/lib/ffi/struct.rb
CHANGED
@@ -1,3 +1,33 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (C) 2008, 2009 Wayne Meissner
|
3
|
+
# Copyright (C) 2008, 2009 Andrea Fazzi
|
4
|
+
# Copyright (C) 2008, 2009 Luc Heinrich
|
5
|
+
#
|
6
|
+
# All rights reserved.
|
7
|
+
#
|
8
|
+
# Redistribution and use in source and binary forms, with or without
|
9
|
+
# modification, are permitted provided that the following conditions are met:
|
10
|
+
#
|
11
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
12
|
+
# list of conditions and the following disclaimer.
|
13
|
+
# * Redistributions in binary form must reproduce the above copyright notice
|
14
|
+
# this list of conditions and the following disclaimer in the documentation
|
15
|
+
# and/or other materials provided with the distribution.
|
16
|
+
# * Neither the name of the Evan Phoenix nor the names of its contributors
|
17
|
+
# may be used to endorse or promote products derived from this software
|
18
|
+
# without specific prior written permission.
|
19
|
+
#
|
20
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
21
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
22
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
23
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
24
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
25
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
26
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
27
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
28
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
29
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
|
1
31
|
require 'ffi/platform'
|
2
32
|
module FFI
|
3
33
|
|
@@ -10,6 +40,28 @@ module FFI
|
|
10
40
|
def offset_of(field_name)
|
11
41
|
self[field_name].offset
|
12
42
|
end
|
43
|
+
|
44
|
+
class Enum < Field
|
45
|
+
|
46
|
+
def get(ptr)
|
47
|
+
type.find(ptr.get_int(offset))
|
48
|
+
end
|
49
|
+
|
50
|
+
def put(ptr, value)
|
51
|
+
ptr.put_int(offset, type.find(value))
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
class InlineStruct < Field
|
57
|
+
def get(ptr)
|
58
|
+
type.struct_class.new(ptr.slice(self.offset, self.size))
|
59
|
+
end
|
60
|
+
|
61
|
+
# def put(ptr, value)
|
62
|
+
# raise TypeError, "wrong value type (expected #{type.struct_class}" unless value.is_a(type.struct_class)
|
63
|
+
# end
|
64
|
+
end
|
13
65
|
end
|
14
66
|
|
15
67
|
|
@@ -131,7 +183,9 @@ module FFI
|
|
131
183
|
end
|
132
184
|
|
133
185
|
def find_type(type, mod = nil)
|
134
|
-
if
|
186
|
+
if type.kind_of?(Class) && type < FFI::Struct
|
187
|
+
FFI::Type::Struct.new(type)
|
188
|
+
elsif type.is_a?(::Array)
|
135
189
|
type
|
136
190
|
elsif mod
|
137
191
|
mod.find_type(type)
|
data/lib/ffi/types.rb
CHANGED
@@ -1,3 +1,32 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (C) 2008, 2009 Wayne Meissner
|
3
|
+
# Copyright (C) 2009 Luc Heinrich
|
4
|
+
# Copyright (c) 2007, 2008 Evan Phoenix
|
5
|
+
# All rights reserved.
|
6
|
+
#
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
8
|
+
# modification, are permitted provided that the following conditions are met:
|
9
|
+
#
|
10
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
11
|
+
# list of conditions and the following disclaimer.
|
12
|
+
# * Redistributions in binary form must reproduce the above copyright notice
|
13
|
+
# this list of conditions and the following disclaimer in the documentation
|
14
|
+
# and/or other materials provided with the distribution.
|
15
|
+
# * Neither the name of the Evan Phoenix nor the names of its contributors
|
16
|
+
# may be used to endorse or promote products derived from this software
|
17
|
+
# without specific prior written permission.
|
18
|
+
#
|
19
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
20
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
22
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
23
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
24
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
25
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
26
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
27
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
|
+
|
1
30
|
module FFI
|
2
31
|
# TypeDefs = Hash.new
|
3
32
|
def self.add_typedef(current, add)
|
data/lib/ffi/variadic.rb
CHANGED
@@ -1,3 +1,32 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (C) 2008, 2009 Wayne Meissner
|
3
|
+
# Copyright (C) 2009 Luc Heinrich
|
4
|
+
#
|
5
|
+
# All rights reserved.
|
6
|
+
#
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
8
|
+
# modification, are permitted provided that the following conditions are met:
|
9
|
+
#
|
10
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
11
|
+
# list of conditions and the following disclaimer.
|
12
|
+
# * Redistributions in binary form must reproduce the above copyright notice
|
13
|
+
# this list of conditions and the following disclaimer in the documentation
|
14
|
+
# and/or other materials provided with the distribution.
|
15
|
+
# * Neither the name of the Evan Phoenix nor the names of its contributors
|
16
|
+
# may be used to endorse or promote products derived from this software
|
17
|
+
# without specific prior written permission.
|
18
|
+
#
|
19
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
20
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
22
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
23
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
24
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
25
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
26
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
27
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
|
+
|
1
30
|
module FFI
|
2
31
|
class VariadicInvoker
|
3
32
|
def init(arg_types, type_map)
|
data/spec/ffi/library_spec.rb
CHANGED
@@ -1,19 +1,20 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
2
2
|
describe "Library" do
|
3
3
|
|
4
|
-
unless Config::CONFIG['target_os'] =~ /mingw/
|
4
|
+
unless Config::CONFIG['target_os'] =~ /mswin|mingw/
|
5
5
|
it "attach_function with no library specified" do
|
6
6
|
lambda {
|
7
7
|
Module.new do |m|
|
8
8
|
m.extend FFI::Library
|
9
9
|
attach_function :getpid, [ ], :uint
|
10
10
|
end
|
11
|
-
}.
|
11
|
+
}.should raise_error
|
12
12
|
end
|
13
13
|
it "attach_function :getpid from this process" do
|
14
14
|
lambda {
|
15
15
|
Module.new do |m|
|
16
16
|
m.extend FFI::Library
|
17
|
+
ffi_lib FFI::Library::CURRENT_PROCESS
|
17
18
|
attach_function :getpid, [ ], :uint
|
18
19
|
end.getpid.should == Process.pid
|
19
20
|
}.should_not raise_error
|
@@ -22,7 +23,7 @@ describe "Library" do
|
|
22
23
|
lambda {
|
23
24
|
Module.new do |m|
|
24
25
|
m.extend FFI::Library
|
25
|
-
ffi_lib 'c', 'libc.so.6'
|
26
|
+
ffi_lib [ 'c', 'libc.so.6' ]
|
26
27
|
attach_function :getpid, [ ], :uint
|
27
28
|
end.getpid.should == Process.pid
|
28
29
|
}.should_not raise_error
|
@@ -31,7 +32,7 @@ describe "Library" do
|
|
31
32
|
lambda {
|
32
33
|
Module.new do |m|
|
33
34
|
m.extend FFI::Library
|
34
|
-
ffi_lib 'libc.so.6', 'c'
|
35
|
+
ffi_lib [ 'libc.so.6', 'c' ]
|
35
36
|
attach_function :getpid, [ ], :uint
|
36
37
|
end.getpid.should == Process.pid
|
37
38
|
}.should_not raise_error
|
@@ -40,7 +41,7 @@ describe "Library" do
|
|
40
41
|
lambda {
|
41
42
|
Module.new do |m|
|
42
43
|
m.extend FFI::Library
|
43
|
-
ffi_lib 'libfubar.so.0xdeadbeef', nil, 'c'
|
44
|
+
ffi_lib [ 'libfubar.so.0xdeadbeef', nil, 'c' ]
|
44
45
|
attach_function :getpid, [ ], :uint
|
45
46
|
end.getpid.should == Process.pid
|
46
47
|
}.should_not raise_error
|
@@ -145,4 +146,29 @@ describe "Library" do
|
|
145
146
|
lib.gvar = val
|
146
147
|
lib.get.should == val
|
147
148
|
end
|
149
|
+
|
150
|
+
[ 0, 0x7fffffff, -0x80000000, -1 ].each do |i|
|
151
|
+
it "structure" do
|
152
|
+
class GlobalStruct < FFI::Struct
|
153
|
+
layout :data, :long
|
154
|
+
end
|
155
|
+
|
156
|
+
lib = Module.new do |m|
|
157
|
+
m.extend FFI::Library
|
158
|
+
ffi_lib TestLibrary::PATH
|
159
|
+
attach_variable :gvar, "gvar_gstruct", GlobalStruct
|
160
|
+
attach_function :get, "gvar_gstruct_get", [], GlobalStruct
|
161
|
+
attach_function :set, "gvar_gstruct_set", [ GlobalStruct ], :void
|
162
|
+
end
|
163
|
+
|
164
|
+
val = GlobalStruct.new
|
165
|
+
val[:data] = i
|
166
|
+
lib.set(val)
|
167
|
+
lib.gvar[:data].should == i
|
168
|
+
val[:data] = 0
|
169
|
+
lib.gvar[:data] = i
|
170
|
+
val = GlobalStruct.new(lib.get)
|
171
|
+
val[:data].should == i
|
172
|
+
end
|
173
|
+
end
|
148
174
|
end
|
data/spec/ffi/spec_helper.rb
CHANGED
@@ -2,10 +2,14 @@ require 'rubygems'
|
|
2
2
|
require 'rbconfig'
|
3
3
|
require 'spec'
|
4
4
|
|
5
|
-
if
|
5
|
+
if RUBY_PLATFORM =~/java/
|
6
|
+
libdir = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "lib"))
|
7
|
+
$:.reject! { |p| p == libdir }
|
8
|
+
else
|
6
9
|
$:.unshift File.join(File.dirname(__FILE__), "..", "..", "lib"),
|
7
10
|
File.join(File.dirname(__FILE__), "..", "..", "build", "#{Config::CONFIG['host_cpu''arch']}", "ffi_c", RUBY_VERSION)
|
8
11
|
end
|
12
|
+
puts "loadpath=#{$:.join(':')}"
|
9
13
|
require "ffi"
|
10
14
|
|
11
15
|
module TestLibrary
|
data/spec/ffi/struct_spec.rb
CHANGED
@@ -133,6 +133,24 @@ describe "Struct tests" do
|
|
133
133
|
mp.get_int64(ll_off).should == 0xfee1deadbeef
|
134
134
|
end
|
135
135
|
end
|
136
|
+
|
137
|
+
it "subclass overrides initialize without calling super" do
|
138
|
+
class InitializeWithoutSuper < FFI::Struct
|
139
|
+
layout :a, :int, :b, :long_long, :d, [:double, 2]
|
140
|
+
|
141
|
+
def initialize(a, b)
|
142
|
+
self[:a] = a
|
143
|
+
self[:b] = b
|
144
|
+
self[:d][0] = 1.2
|
145
|
+
self[:d][1] = 3.4
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
s = InitializeWithoutSuper.new(0x1eefbeef, 0xdeadcafebabe)
|
150
|
+
s[:a].should == 0x1eefbeef
|
151
|
+
s[:b].should == 0xdeadcafebabe
|
152
|
+
end
|
153
|
+
|
136
154
|
it "Can use Struct subclass as parameter type" do
|
137
155
|
module StructParam
|
138
156
|
extend FFI::Library
|
@@ -286,6 +304,20 @@ describe "Struct tests" do
|
|
286
304
|
s[:v] = value
|
287
305
|
(s.pointer.get_double(0) - value).abs.should < 0.0001
|
288
306
|
end
|
307
|
+
module EnumFields
|
308
|
+
extend FFI::Library
|
309
|
+
enum :test_enum, [:c1, 10, :c2, 20, :c3, 30, :c4, 40]
|
310
|
+
class TestStruct < FFI::Struct
|
311
|
+
layout :a, :int, :c, :test_enum
|
312
|
+
end
|
313
|
+
end
|
314
|
+
it ":enum field r/w" do
|
315
|
+
s = EnumFields::TestStruct.new
|
316
|
+
s[:c] = :c3
|
317
|
+
|
318
|
+
s.pointer.get_uint(FFI::Type::INT32.size).should == 30
|
319
|
+
s[:c].should == :c3
|
320
|
+
end
|
289
321
|
module CallbackMember
|
290
322
|
extend FFI::Library
|
291
323
|
ffi_lib TestLibrary::PATH
|
@@ -379,6 +411,56 @@ describe FFI::Struct, ' with a nested struct field' do
|
|
379
411
|
end
|
380
412
|
end
|
381
413
|
|
414
|
+
describe FFI::Struct, ' with a nested array of structs' do
|
415
|
+
module InlineArrayOfStructs
|
416
|
+
extend FFI::Library
|
417
|
+
ffi_lib TestLibrary::PATH
|
418
|
+
class NestedStruct < FFI::Struct
|
419
|
+
layout :i, :int
|
420
|
+
end
|
421
|
+
class ContainerStruct < FFI::Struct
|
422
|
+
layout :first, :char, :ns, [ NestedStruct, 1 ]
|
423
|
+
end
|
424
|
+
attach_function :struct_align_nested_struct, [ :pointer ], :int
|
425
|
+
attach_function :struct_make_container_struct, [ :int ], :pointer
|
426
|
+
end
|
427
|
+
|
428
|
+
before do
|
429
|
+
@cs = InlineArrayOfStructs::ContainerStruct.new
|
430
|
+
end
|
431
|
+
|
432
|
+
it 'should align correctly nested struct field' do
|
433
|
+
@cs[:ns][0][:i] = 123
|
434
|
+
InlineArrayOfStructs.struct_align_nested_struct(@cs.to_ptr).should == 123
|
435
|
+
end
|
436
|
+
|
437
|
+
it 'should correctly calculate Container size (in bytes)' do
|
438
|
+
InlineArrayOfStructs::ContainerStruct.size.should == 8
|
439
|
+
end
|
440
|
+
|
441
|
+
it 'should return a Struct object when the field is accessed' do
|
442
|
+
@cs[:ns][0].is_a?(FFI::Struct).should be_true
|
443
|
+
end
|
444
|
+
|
445
|
+
it 'should read a value from memory' do
|
446
|
+
@cs = InlineArrayOfStructs::ContainerStruct.new(InlineArrayOfStructs.struct_make_container_struct(123))
|
447
|
+
@cs[:ns][0][:i].should == 123
|
448
|
+
end
|
449
|
+
|
450
|
+
it 'should write a value to memory' do
|
451
|
+
@cs = InlineArrayOfStructs::ContainerStruct.new(InlineArrayOfStructs.struct_make_container_struct(123))
|
452
|
+
@cs[:ns][0][:i] = 456
|
453
|
+
InlineArrayOfStructs.struct_align_nested_struct(@cs.to_ptr).should == 456
|
454
|
+
end
|
455
|
+
|
456
|
+
it 'should support Enumerable#each' do
|
457
|
+
@cs = InlineArrayOfStructs::ContainerStruct.new(InlineArrayOfStructs.struct_make_container_struct(123))
|
458
|
+
ints = []
|
459
|
+
@cs[:ns].each { |s| ints << s[:i] }
|
460
|
+
ints[0].should == 123
|
461
|
+
end
|
462
|
+
end
|
463
|
+
|
382
464
|
describe FFI::Struct, ' by value' do
|
383
465
|
module LibTest
|
384
466
|
extend FFI::Library
|