ffi 1.10.0 → 1.11.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.gitmodules +2 -1
- data/.travis.yml +17 -18
- data/CHANGELOG.md +33 -0
- data/Gemfile +1 -1
- data/README.md +20 -17
- data/Rakefile +10 -83
- data/appveyor.yml +6 -1
- data/ext/ffi_c/Call.c +16 -33
- data/ext/ffi_c/Call.h +2 -5
- data/ext/ffi_c/Function.c +24 -108
- data/ext/ffi_c/Platform.c +0 -47
- data/ext/ffi_c/Thread.c +6 -222
- data/ext/ffi_c/Thread.h +2 -13
- data/ext/ffi_c/Type.c +0 -18
- data/ext/ffi_c/Type.h +0 -1
- data/ext/ffi_c/Variadic.c +9 -15
- data/ext/ffi_c/extconf.rb +34 -20
- data/ext/ffi_c/ffi.c +3 -8
- data/ext/ffi_c/libffi/configure.ac +5 -1
- data/ext/ffi_c/libffi/include/ffi_common.h +1 -1
- data/ext/ffi_c/libffi/src/aarch64/ffi.c +2 -2
- data/ext/ffi_c/libffi/src/frv/ffi.c +1 -1
- data/ext/ffi_c/libffi/src/metag/ffi.c +1 -1
- data/ext/ffi_c/libffi/src/moxie/ffi.c +1 -1
- data/ext/ffi_c/libffi/src/riscv/ffi.c +42 -6
- data/ext/ffi_c/libffi/src/riscv/ffitarget.h +1 -0
- data/ext/ffi_c/libffi/src/riscv/sysv.S +86 -7
- data/ext/ffi_c/libffi/src/x86/ffi.c +2 -1
- data/ext/ffi_c/libffi/src/x86/ffiw64.c +1 -1
- data/ext/ffi_c/libffi/src/x86/sysv.S +88 -2
- data/ext/ffi_c/libffi/src/x86/unix64.S +41 -0
- data/ext/ffi_c/rbffi.h +0 -2
- data/ffi.gemspec +11 -4
- data/lib/ffi/data_converter.rb +67 -0
- data/lib/ffi/ffi.rb +1 -0
- data/lib/ffi/platform.rb +2 -0
- data/lib/ffi/pointer.rb +1 -1
- data/lib/ffi/struct.rb +3 -63
- data/lib/ffi/struct_by_reference.rb +72 -0
- data/lib/ffi/struct_layout.rb +96 -0
- data/lib/ffi/tools/const_generator.rb +5 -4
- data/lib/ffi/tools/generator.rb +47 -2
- data/lib/ffi/tools/generator_task.rb +13 -17
- data/lib/ffi/tools/struct_generator.rb +4 -4
- data/lib/ffi/types.rb +1 -1
- data/lib/ffi/version.rb +1 -1
- metadata +18 -13
- data/ext/ffi_c/DataConverter.c +0 -91
- data/ext/ffi_c/StructByReference.c +0 -190
- data/ext/ffi_c/StructByReference.h +0 -50
@@ -177,7 +177,7 @@ ffi_prep_cif_machdep(ffi_cif *cif)
|
|
177
177
|
bytes = FFI_ALIGN (bytes, t->alignment);
|
178
178
|
bytes += FFI_ALIGN (t->size, FFI_SIZEOF_ARG);
|
179
179
|
}
|
180
|
-
cif->bytes = FFI_ALIGN (bytes,
|
180
|
+
cif->bytes = FFI_ALIGN (bytes, FFI_SIZEOF_ARG);
|
181
181
|
|
182
182
|
return FFI_OK;
|
183
183
|
}
|
@@ -545,6 +545,7 @@ ffi_prep_closure_loc (ffi_closure* closure,
|
|
545
545
|
case FFI_REGISTER:
|
546
546
|
dest = ffi_closure_REGISTER;
|
547
547
|
op = 0x68; /* pushl imm */
|
548
|
+
break;
|
548
549
|
default:
|
549
550
|
return FFI_BAD_ABI;
|
550
551
|
}
|
@@ -792,9 +792,9 @@ ENDF(C(ffi_closure_raw_THISCALL))
|
|
792
792
|
|
793
793
|
#ifdef X86_DARWIN
|
794
794
|
# define COMDAT(X) \
|
795
|
-
.section __TEXT,
|
795
|
+
.section __TEXT,__text,coalesced,pure_instructions; \
|
796
796
|
.weak_definition X; \
|
797
|
-
|
797
|
+
FFI_HIDDEN(X)
|
798
798
|
#elif defined __ELF__ && !(defined(__sun__) && defined(__svr4__))
|
799
799
|
# define COMDAT(X) \
|
800
800
|
.section .text.X,"axG",@progbits,X,comdat; \
|
@@ -1035,6 +1035,92 @@ L(SFDE9):
|
|
1035
1035
|
L(EFDE9):
|
1036
1036
|
#endif /* !FFI_NO_RAW_API */
|
1037
1037
|
|
1038
|
+
#ifdef _WIN32
|
1039
|
+
.def @feat.00;
|
1040
|
+
.scl 3;
|
1041
|
+
.type 0;
|
1042
|
+
.endef
|
1043
|
+
.globl @feat.00
|
1044
|
+
@feat.00 = 1
|
1045
|
+
#endif
|
1046
|
+
|
1047
|
+
#ifdef __APPLE__
|
1048
|
+
.subsections_via_symbols
|
1049
|
+
.section __LD,__compact_unwind,regular,debug
|
1050
|
+
|
1051
|
+
/* compact unwind for ffi_call_i386 */
|
1052
|
+
.long C(ffi_call_i386)
|
1053
|
+
.set L1,L(UW5)-L(UW0)
|
1054
|
+
.long L1
|
1055
|
+
.long 0x04000000 /* use dwarf unwind info */
|
1056
|
+
.long 0
|
1057
|
+
.long 0
|
1058
|
+
|
1059
|
+
/* compact unwind for ffi_go_closure_EAX */
|
1060
|
+
.long C(ffi_go_closure_EAX)
|
1061
|
+
.set L2,L(UW8)-L(UW6)
|
1062
|
+
.long L2
|
1063
|
+
.long 0x04000000 /* use dwarf unwind info */
|
1064
|
+
.long 0
|
1065
|
+
.long 0
|
1066
|
+
|
1067
|
+
/* compact unwind for ffi_go_closure_ECX */
|
1068
|
+
.long C(ffi_go_closure_ECX)
|
1069
|
+
.set L3,L(UW11)-L(UW9)
|
1070
|
+
.long L3
|
1071
|
+
.long 0x04000000 /* use dwarf unwind info */
|
1072
|
+
.long 0
|
1073
|
+
.long 0
|
1074
|
+
|
1075
|
+
/* compact unwind for ffi_closure_i386 */
|
1076
|
+
.long C(ffi_closure_i386)
|
1077
|
+
.set L4,L(UW20)-L(UW12)
|
1078
|
+
.long L4
|
1079
|
+
.long 0x04000000 /* use dwarf unwind info */
|
1080
|
+
.long 0
|
1081
|
+
.long 0
|
1082
|
+
|
1083
|
+
/* compact unwind for ffi_go_closure_STDCALL */
|
1084
|
+
.long C(ffi_go_closure_STDCALL)
|
1085
|
+
.set L5,L(UW23)-L(UW21)
|
1086
|
+
.long L5
|
1087
|
+
.long 0x04000000 /* use dwarf unwind info */
|
1088
|
+
.long 0
|
1089
|
+
.long 0
|
1090
|
+
|
1091
|
+
/* compact unwind for ffi_closure_REGISTER */
|
1092
|
+
.long C(ffi_closure_REGISTER)
|
1093
|
+
.set L6,L(UW26)-L(UW24)
|
1094
|
+
.long L6
|
1095
|
+
.long 0x04000000 /* use dwarf unwind info */
|
1096
|
+
.long 0
|
1097
|
+
.long 0
|
1098
|
+
|
1099
|
+
/* compact unwind for ffi_closure_STDCALL */
|
1100
|
+
.long C(ffi_closure_STDCALL)
|
1101
|
+
.set L7,L(UW31)-L(UW27)
|
1102
|
+
.long L7
|
1103
|
+
.long 0x04000000 /* use dwarf unwind info */
|
1104
|
+
.long 0
|
1105
|
+
.long 0
|
1106
|
+
|
1107
|
+
/* compact unwind for ffi_closure_raw_SYSV */
|
1108
|
+
.long C(ffi_closure_raw_SYSV)
|
1109
|
+
.set L8,L(UW40)-L(UW32)
|
1110
|
+
.long L8
|
1111
|
+
.long 0x04000000 /* use dwarf unwind info */
|
1112
|
+
.long 0
|
1113
|
+
.long 0
|
1114
|
+
|
1115
|
+
/* compact unwind for ffi_closure_raw_THISCALL */
|
1116
|
+
.long C(ffi_closure_raw_THISCALL)
|
1117
|
+
.set L9,L(UW52)-L(UW41)
|
1118
|
+
.long L9
|
1119
|
+
.long 0x04000000 /* use dwarf unwind info */
|
1120
|
+
.long 0
|
1121
|
+
.long 0
|
1122
|
+
#endif /* __APPLE__ */
|
1123
|
+
|
1038
1124
|
#endif /* ifndef _MSC_VER */
|
1039
1125
|
#endif /* ifndef __x86_64__ */
|
1040
1126
|
|
@@ -517,6 +517,47 @@ L(SFDE5):
|
|
517
517
|
L(EFDE5):
|
518
518
|
#ifdef __APPLE__
|
519
519
|
.subsections_via_symbols
|
520
|
+
.section __LD,__compact_unwind,regular,debug
|
521
|
+
|
522
|
+
/* compact unwind for ffi_call_unix64 */
|
523
|
+
.quad C(ffi_call_unix64)
|
524
|
+
.set L1,L(UW4)-L(UW0)
|
525
|
+
.long L1
|
526
|
+
.long 0x04000000 /* use dwarf unwind info */
|
527
|
+
.quad 0
|
528
|
+
.quad 0
|
529
|
+
|
530
|
+
/* compact unwind for ffi_closure_unix64_sse */
|
531
|
+
.quad C(ffi_closure_unix64_sse)
|
532
|
+
.set L2,L(UW7)-L(UW5)
|
533
|
+
.long L2
|
534
|
+
.long 0x04000000 /* use dwarf unwind info */
|
535
|
+
.quad 0
|
536
|
+
.quad 0
|
537
|
+
|
538
|
+
/* compact unwind for ffi_closure_unix64 */
|
539
|
+
.quad C(ffi_closure_unix64)
|
540
|
+
.set L3,L(UW11)-L(UW8)
|
541
|
+
.long L3
|
542
|
+
.long 0x04000000 /* use dwarf unwind info */
|
543
|
+
.quad 0
|
544
|
+
.quad 0
|
545
|
+
|
546
|
+
/* compact unwind for ffi_go_closure_unix64_sse */
|
547
|
+
.quad C(ffi_go_closure_unix64_sse)
|
548
|
+
.set L4,L(UW14)-L(UW12)
|
549
|
+
.long L4
|
550
|
+
.long 0x04000000 /* use dwarf unwind info */
|
551
|
+
.quad 0
|
552
|
+
.quad 0
|
553
|
+
|
554
|
+
/* compact unwind for ffi_go_closure_unix64 */
|
555
|
+
.quad C(ffi_go_closure_unix64)
|
556
|
+
.set L5,L(UW17)-L(UW15)
|
557
|
+
.long L5
|
558
|
+
.long 0x04000000 /* use dwarf unwind info */
|
559
|
+
.quad 0
|
560
|
+
.quad 0
|
520
561
|
#endif
|
521
562
|
|
522
563
|
#endif /* __x86_64__ */
|
data/ext/ffi_c/rbffi.h
CHANGED
@@ -44,7 +44,6 @@ extern void rbffi_Type_Init(VALUE ffiModule);
|
|
44
44
|
extern void rbffi_Buffer_Init(VALUE ffiModule);
|
45
45
|
extern void rbffi_Invoker_Init(VALUE ffiModule);
|
46
46
|
extern void rbffi_Variadic_Init(VALUE ffiModule);
|
47
|
-
extern void rbffi_DataConverter_Init(VALUE ffiModule);
|
48
47
|
extern VALUE rbffi_AbstractMemoryClass, rbffi_InvokerClass;
|
49
48
|
extern int rbffi_type_size(VALUE type);
|
50
49
|
extern void rbffi_Thread_Init(VALUE moduleFFI);
|
@@ -54,4 +53,3 @@ extern void rbffi_Thread_Init(VALUE moduleFFI);
|
|
54
53
|
#endif
|
55
54
|
|
56
55
|
#endif /* RBFFI_RBFFI_H */
|
57
|
-
|
data/ffi.gemspec
CHANGED
@@ -8,6 +8,14 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.homepage = 'http://wiki.github.com/ffi/ffi'
|
9
9
|
s.summary = 'Ruby FFI'
|
10
10
|
s.description = 'Ruby FFI library'
|
11
|
+
if s.respond_to?(:metadata)
|
12
|
+
s.metadata['bug_tracker_uri'] = 'https://github.com/ffi/ffi/issues'
|
13
|
+
s.metadata['changelog_uri'] = 'https://github.com/ffi/ffi/blob/master/CHANGELOG.md'
|
14
|
+
s.metadata['documentation_uri'] = 'https://github.com/ffi/ffi/wiki'
|
15
|
+
s.metadata['wiki_uri'] = 'https://github.com/ffi/ffi/wiki'
|
16
|
+
s.metadata['source_code_uri'] = 'https://github.com/ffi/ffi/'
|
17
|
+
s.metadata['mailing_list_uri'] = 'http://groups.google.com/group/ruby-ffi'
|
18
|
+
end
|
11
19
|
s.files = `git ls-files -z`.split("\x0").reject do |f|
|
12
20
|
f =~ /^(bench|gen|libtest|nbproject|spec)/
|
13
21
|
end
|
@@ -23,14 +31,13 @@ Gem::Specification.new do |s|
|
|
23
31
|
end
|
24
32
|
|
25
33
|
s.extensions << 'ext/ffi_c/extconf.rb'
|
26
|
-
s.has_rdoc = false
|
27
34
|
s.rdoc_options = %w[--exclude=ext/ffi_c/.*\.o$ --exclude=ffi_c\.(bundle|so)$]
|
28
35
|
s.license = 'BSD-3-Clause'
|
29
36
|
s.require_paths << 'ext/ffi_c'
|
30
|
-
s.required_ruby_version = '>=
|
31
|
-
s.add_development_dependency 'rake', '~>
|
37
|
+
s.required_ruby_version = '>= 2.0'
|
38
|
+
s.add_development_dependency 'rake', '~> 12.1'
|
32
39
|
s.add_development_dependency 'rake-compiler', '~> 1.0'
|
33
|
-
s.add_development_dependency 'rake-compiler-dock', '~> 0.
|
40
|
+
s.add_development_dependency 'rake-compiler-dock', '~> 0.7.0'
|
34
41
|
s.add_development_dependency 'rspec', '~> 2.14.1'
|
35
42
|
s.add_development_dependency 'rubygems-tasks', "~> 0.2.4"
|
36
43
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (C) 2008-2010 Wayne Meissner
|
3
|
+
#
|
4
|
+
# This file is part of ruby-ffi.
|
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 Ruby FFI project 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
|
+
|
31
|
+
module FFI
|
32
|
+
# This module is used to extend somes classes and give then a common API.
|
33
|
+
#
|
34
|
+
# Most of methods defined here must be overriden.
|
35
|
+
module DataConverter
|
36
|
+
# Get native type.
|
37
|
+
#
|
38
|
+
# @overload native_type(type)
|
39
|
+
# @param [String, Symbol, Type] type
|
40
|
+
# @return [Type]
|
41
|
+
# Get native type from +type+.
|
42
|
+
#
|
43
|
+
# @overload native_type
|
44
|
+
# @raise {NotImplementedError} This method must be overriden.
|
45
|
+
def native_type(type = nil)
|
46
|
+
if type
|
47
|
+
@native_type = FFI.find_type(type)
|
48
|
+
else
|
49
|
+
native_type = @native_type
|
50
|
+
unless native_type
|
51
|
+
raise NotImplementedError, 'native_type method not overridden and no native_type set'
|
52
|
+
end
|
53
|
+
native_type
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Convert to a native type.
|
58
|
+
def to_native(value, ctx)
|
59
|
+
value
|
60
|
+
end
|
61
|
+
|
62
|
+
# Convert from a native type.
|
63
|
+
def from_native(value, ctx)
|
64
|
+
value
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/ffi/ffi.rb
CHANGED
data/lib/ffi/platform.rb
CHANGED
data/lib/ffi/pointer.rb
CHANGED
data/lib/ffi/struct.rb
CHANGED
@@ -32,72 +32,12 @@
|
|
32
32
|
#
|
33
33
|
|
34
34
|
require 'ffi/platform'
|
35
|
+
require 'ffi/struct_layout'
|
35
36
|
require 'ffi/struct_layout_builder'
|
37
|
+
require 'ffi/struct_by_reference'
|
36
38
|
|
37
39
|
module FFI
|
38
40
|
|
39
|
-
class StructLayout
|
40
|
-
|
41
|
-
# @return [Array<Array(Symbol, Numeric)>
|
42
|
-
# Get an array of tuples (field name, offset of the field).
|
43
|
-
def offsets
|
44
|
-
members.map { |m| [ m, self[m].offset ] }
|
45
|
-
end
|
46
|
-
|
47
|
-
# @return [Numeric]
|
48
|
-
# Get the offset of a field.
|
49
|
-
def offset_of(field_name)
|
50
|
-
self[field_name].offset
|
51
|
-
end
|
52
|
-
|
53
|
-
# An enum {Field} in a {StructLayout}.
|
54
|
-
class Enum < Field
|
55
|
-
|
56
|
-
# @param [AbstractMemory] ptr pointer on a {Struct}
|
57
|
-
# @return [Object]
|
58
|
-
# Get an object of type {#type} from memory pointed by +ptr+.
|
59
|
-
def get(ptr)
|
60
|
-
type.find(ptr.get_int(offset))
|
61
|
-
end
|
62
|
-
|
63
|
-
# @param [AbstractMemory] ptr pointer on a {Struct}
|
64
|
-
# @param value
|
65
|
-
# @return [nil]
|
66
|
-
# Set +value+ into memory pointed by +ptr+.
|
67
|
-
def put(ptr, value)
|
68
|
-
ptr.put_int(offset, type.find(value))
|
69
|
-
end
|
70
|
-
|
71
|
-
end
|
72
|
-
|
73
|
-
class InnerStruct < Field
|
74
|
-
def get(ptr)
|
75
|
-
type.struct_class.new(ptr.slice(self.offset, self.size))
|
76
|
-
end
|
77
|
-
|
78
|
-
def put(ptr, value)
|
79
|
-
raise TypeError, "wrong value type (expected #{type.struct_class})" unless value.is_a?(type.struct_class)
|
80
|
-
ptr.slice(self.offset, self.size).__copy_from__(value.pointer, self.size)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
class Mapped < Field
|
85
|
-
def initialize(name, offset, type, orig_field)
|
86
|
-
super(name, offset, type)
|
87
|
-
@orig_field = orig_field
|
88
|
-
end
|
89
|
-
|
90
|
-
def get(ptr)
|
91
|
-
type.from_native(@orig_field.get(ptr), nil)
|
92
|
-
end
|
93
|
-
|
94
|
-
def put(ptr, value)
|
95
|
-
@orig_field.put(ptr, type.to_native(value, nil))
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
|
101
41
|
class Struct
|
102
42
|
|
103
43
|
# Get struct size
|
@@ -296,7 +236,7 @@ module FFI
|
|
296
236
|
@packed = packed
|
297
237
|
end
|
298
238
|
alias :pack :packed
|
299
|
-
|
239
|
+
|
300
240
|
def aligned(alignment = 1)
|
301
241
|
@min_alignment = alignment
|
302
242
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (C) 2010 Wayne Meissner
|
3
|
+
#
|
4
|
+
# This file is part of ruby-ffi.
|
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 Ruby FFI project 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
|
+
|
31
|
+
module FFI
|
32
|
+
# This class includes the {FFI::DataConverter} module.
|
33
|
+
class StructByReference
|
34
|
+
include DataConverter
|
35
|
+
|
36
|
+
attr_reader :struct_class
|
37
|
+
|
38
|
+
# @param [Struct] struct_class
|
39
|
+
def initialize(struct_class)
|
40
|
+
unless Class === struct_class and struct_class < FFI::Struct
|
41
|
+
raise TypeError, 'wrong type (expected subclass of FFI::Struct)'
|
42
|
+
end
|
43
|
+
@struct_class = struct_class
|
44
|
+
end
|
45
|
+
|
46
|
+
# Always get {FFI::Type}::POINTER.
|
47
|
+
def native_type
|
48
|
+
FFI::Type::POINTER
|
49
|
+
end
|
50
|
+
|
51
|
+
# @param [nil, Struct] value
|
52
|
+
# @param [nil] ctx
|
53
|
+
# @return [AbstractMemory] Pointer on +value+.
|
54
|
+
def to_native(value, ctx)
|
55
|
+
return Pointer::NULL if value.nil?
|
56
|
+
|
57
|
+
unless @struct_class === value
|
58
|
+
raise TypeError, "wrong argument type #{value.class} (expected #{@struct_class})"
|
59
|
+
end
|
60
|
+
|
61
|
+
value.pointer
|
62
|
+
end
|
63
|
+
|
64
|
+
# @param [AbstractMemory] value
|
65
|
+
# @param [nil] ctx
|
66
|
+
# @return [Struct]
|
67
|
+
# Create a struct from content of memory +value+.
|
68
|
+
def from_native(value, ctx)
|
69
|
+
@struct_class.new(value)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|