ffi 0.4.0 → 0.5.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.
- data/README.rdoc +15 -15
- data/Rakefile +57 -8
- data/ext/ffi_c/AbstractMemory.c +101 -24
- data/ext/ffi_c/AbstractMemory.h +98 -6
- data/ext/ffi_c/ArrayType.c +129 -0
- data/ext/ffi_c/ArrayType.h +58 -0
- data/ext/ffi_c/AutoPointer.c +1 -0
- data/ext/ffi_c/Buffer.c +59 -43
- data/ext/ffi_c/Call.c +853 -0
- data/ext/ffi_c/Call.h +86 -0
- data/ext/ffi_c/ClosurePool.c +302 -0
- data/ext/ffi_c/ClosurePool.h +29 -0
- data/ext/ffi_c/DynamicLibrary.c +3 -0
- data/ext/ffi_c/Function.c +478 -0
- data/ext/ffi_c/Function.h +80 -0
- data/ext/ffi_c/FunctionInfo.c +221 -0
- data/ext/ffi_c/LastError.c +30 -6
- data/ext/ffi_c/MemoryPointer.c +50 -28
- data/ext/ffi_c/MethodHandle.c +346 -0
- data/ext/ffi_c/MethodHandle.h +53 -0
- data/ext/ffi_c/Pointer.c +73 -13
- data/ext/ffi_c/Pointer.h +31 -7
- data/ext/ffi_c/Struct.c +517 -224
- data/ext/ffi_c/Struct.h +60 -6
- data/ext/ffi_c/StructByValue.c +140 -0
- data/ext/ffi_c/StructByValue.h +53 -0
- data/ext/ffi_c/StructLayout.c +450 -0
- data/ext/ffi_c/Type.c +121 -22
- data/ext/ffi_c/Type.h +37 -8
- data/ext/ffi_c/Types.c +46 -61
- data/ext/ffi_c/Types.h +38 -7
- data/ext/ffi_c/Variadic.c +260 -0
- data/ext/ffi_c/compat.h +53 -3
- data/ext/ffi_c/extconf.rb +6 -7
- data/ext/ffi_c/ffi.c +45 -39
- data/ext/ffi_c/libffi.darwin.mk +2 -2
- data/ext/ffi_c/rbffi.h +3 -0
- data/lib/ffi/ffi.rb +7 -4
- data/lib/ffi/library.rb +34 -59
- data/lib/ffi/platform.rb +14 -4
- data/lib/ffi/struct.rb +110 -281
- data/lib/ffi/union.rb +4 -9
- data/lib/ffi/variadic.rb +1 -6
- data/spec/ffi/buffer_spec.rb +6 -0
- data/spec/ffi/callback_spec.rb +34 -3
- data/spec/ffi/function_spec.rb +73 -0
- data/spec/ffi/library_spec.rb +56 -52
- data/spec/ffi/pointer_spec.rb +3 -3
- data/spec/ffi/struct_callback_spec.rb +26 -3
- data/spec/ffi/struct_spec.rb +56 -3
- metadata +42 -11
- data/ext/ffi_c/Callback.c +0 -374
- data/ext/ffi_c/Callback.h +0 -47
- data/ext/ffi_c/Invoker.c +0 -962
- data/ext/ffi_c/NullPointer.c +0 -143
@@ -0,0 +1,260 @@
|
|
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
|
+
* * The name of the author or authors may not be used to endorse or promote
|
14
|
+
* products derived from this software without specific prior written permission.
|
15
|
+
*
|
16
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
17
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
18
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
19
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
20
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
21
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
22
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
23
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
24
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
25
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
26
|
+
*/
|
27
|
+
|
28
|
+
#include <sys/param.h>
|
29
|
+
#include <sys/types.h>
|
30
|
+
|
31
|
+
#include <stdio.h>
|
32
|
+
#include <stdint.h>
|
33
|
+
#include <stdbool.h>
|
34
|
+
#include <ruby.h>
|
35
|
+
|
36
|
+
#include <ffi.h>
|
37
|
+
#include "rbffi.h"
|
38
|
+
#include "compat.h"
|
39
|
+
|
40
|
+
#include "AbstractMemory.h"
|
41
|
+
#include "Pointer.h"
|
42
|
+
#include "Types.h"
|
43
|
+
#include "Type.h"
|
44
|
+
#include "LastError.h"
|
45
|
+
#include "MethodHandle.h"
|
46
|
+
#include "Call.h"
|
47
|
+
|
48
|
+
typedef struct VariadicInvoker_ {
|
49
|
+
VALUE rbAddress;
|
50
|
+
VALUE rbReturnType;
|
51
|
+
VALUE rbEnums;
|
52
|
+
|
53
|
+
Type* returnType;
|
54
|
+
ffi_abi abi;
|
55
|
+
void* function;
|
56
|
+
int paramCount;
|
57
|
+
} VariadicInvoker;
|
58
|
+
|
59
|
+
|
60
|
+
static VALUE variadic_allocate(VALUE klass);
|
61
|
+
static VALUE variadic_initialize(VALUE self, VALUE rbFunction, VALUE rbParameterTypes,
|
62
|
+
VALUE rbReturnType, VALUE options);
|
63
|
+
static void variadic_mark(VariadicInvoker *);
|
64
|
+
|
65
|
+
static VALUE classVariadicInvoker = Qnil;
|
66
|
+
|
67
|
+
|
68
|
+
static VALUE
|
69
|
+
variadic_allocate(VALUE klass)
|
70
|
+
{
|
71
|
+
VariadicInvoker *invoker;
|
72
|
+
VALUE obj = Data_Make_Struct(klass, VariadicInvoker, variadic_mark, -1, invoker);
|
73
|
+
|
74
|
+
invoker->rbAddress = Qnil;
|
75
|
+
invoker->rbEnums = Qnil;
|
76
|
+
invoker->rbReturnType = Qnil;
|
77
|
+
|
78
|
+
return obj;
|
79
|
+
}
|
80
|
+
|
81
|
+
static void
|
82
|
+
variadic_mark(VariadicInvoker *invoker)
|
83
|
+
{
|
84
|
+
rb_gc_mark(invoker->rbEnums);
|
85
|
+
rb_gc_mark(invoker->rbAddress);
|
86
|
+
rb_gc_mark(invoker->rbReturnType);
|
87
|
+
}
|
88
|
+
|
89
|
+
static VALUE
|
90
|
+
variadic_initialize(VALUE self, VALUE rbFunction, VALUE rbParameterTypes, VALUE rbReturnType, VALUE options)
|
91
|
+
{
|
92
|
+
VariadicInvoker* invoker = NULL;
|
93
|
+
VALUE retval = Qnil;
|
94
|
+
VALUE convention = Qnil;
|
95
|
+
VALUE fixed = Qnil;
|
96
|
+
int i;
|
97
|
+
|
98
|
+
Check_Type(options, T_HASH);
|
99
|
+
convention = rb_hash_aref(options, ID2SYM(rb_intern("convention")));
|
100
|
+
|
101
|
+
Data_Get_Struct(self, VariadicInvoker, invoker);
|
102
|
+
invoker->rbEnums = rb_hash_aref(options, ID2SYM(rb_intern("enums")));
|
103
|
+
invoker->rbAddress = rbFunction;
|
104
|
+
invoker->function = rbffi_AbstractMemory_Cast(rbFunction, rbffi_PointerClass)->address;
|
105
|
+
|
106
|
+
#if defined(_WIN32) || defined(__WIN32__)
|
107
|
+
VALUE rbConventionStr = rb_funcall2(convention, rb_intern("to_s"), 0, NULL);
|
108
|
+
invoker->abi = (RTEST(convention) && strcmp(StringValueCStr(rbConventionStr), "stdcall") == 0)
|
109
|
+
? FFI_STDCALL : FFI_DEFAULT_ABI;
|
110
|
+
#else
|
111
|
+
invoker->abi = FFI_DEFAULT_ABI;
|
112
|
+
#endif
|
113
|
+
|
114
|
+
invoker->rbReturnType = rbffi_Type_Lookup(rbReturnType);
|
115
|
+
if (!RTEST(invoker->rbReturnType)) {
|
116
|
+
VALUE typeName = rb_funcall2(rbReturnType, rb_intern("inspect"), 0, NULL);
|
117
|
+
rb_raise(rb_eTypeError, "Invalid return type (%s)", RSTRING_PTR(typeName));
|
118
|
+
}
|
119
|
+
|
120
|
+
Data_Get_Struct(rbReturnType, Type, invoker->returnType);
|
121
|
+
|
122
|
+
invoker->paramCount = -1;
|
123
|
+
|
124
|
+
fixed = rb_ary_new2(RARRAY_LEN(rbParameterTypes) - 1);
|
125
|
+
for (i = 0; i < RARRAY_LEN(rbParameterTypes); ++i) {
|
126
|
+
VALUE entry = rb_ary_entry(rbParameterTypes, i);
|
127
|
+
VALUE rbType = rbffi_Type_Lookup(entry);
|
128
|
+
Type* type;
|
129
|
+
|
130
|
+
if (!RTEST(rbType)) {
|
131
|
+
VALUE typeName = rb_funcall2(entry, rb_intern("inspect"), 0, NULL);
|
132
|
+
rb_raise(rb_eTypeError, "Invalid parameter type (%s)", RSTRING_PTR(typeName));
|
133
|
+
}
|
134
|
+
Data_Get_Struct(rbType, Type, type);
|
135
|
+
if (type->nativeType != NATIVE_VARARGS) {
|
136
|
+
rb_ary_push(fixed, entry);
|
137
|
+
}
|
138
|
+
}
|
139
|
+
/*
|
140
|
+
* @fixed and @type_map are used by the parameter mangling ruby code
|
141
|
+
*/
|
142
|
+
rb_iv_set(self, "@fixed", fixed);
|
143
|
+
rb_iv_set(self, "@type_map", rb_hash_aref(options, ID2SYM(rb_intern("type_map"))));
|
144
|
+
|
145
|
+
return retval;
|
146
|
+
}
|
147
|
+
|
148
|
+
|
149
|
+
static inline VALUE
|
150
|
+
ffi_invoke(ffi_cif* cif, void* function, Type* returnType, void** ffiValues,
|
151
|
+
VALUE rbReturnType, VALUE rbEnums)
|
152
|
+
{
|
153
|
+
FFIStorage retval;
|
154
|
+
|
155
|
+
#ifdef USE_RAW
|
156
|
+
ffi_raw_call(cif, function, &retval, (ffi_raw *) ffiValues[0]);
|
157
|
+
#else
|
158
|
+
ffi_call(cif, function, &retval, ffiValues);
|
159
|
+
#endif
|
160
|
+
rbffi_save_errno();
|
161
|
+
|
162
|
+
return rbffi_NativeValue_ToRuby(returnType, rbReturnType, &retval, rbEnums);
|
163
|
+
}
|
164
|
+
|
165
|
+
static VALUE
|
166
|
+
variadic_invoke(VALUE self, VALUE parameterTypes, VALUE parameterValues)
|
167
|
+
{
|
168
|
+
VariadicInvoker* invoker;
|
169
|
+
FFIStorage* params;
|
170
|
+
ffi_cif cif;
|
171
|
+
void** ffiValues;
|
172
|
+
ffi_type** ffiParamTypes;
|
173
|
+
ffi_type* ffiReturnType;
|
174
|
+
NativeType* paramTypes;
|
175
|
+
VALUE* argv;
|
176
|
+
int paramCount = 0, i;
|
177
|
+
ffi_status ffiStatus;
|
178
|
+
|
179
|
+
Check_Type(parameterTypes, T_ARRAY);
|
180
|
+
Check_Type(parameterValues, T_ARRAY);
|
181
|
+
|
182
|
+
Data_Get_Struct(self, VariadicInvoker, invoker);
|
183
|
+
paramCount = RARRAY_LEN(parameterTypes);
|
184
|
+
paramTypes = ALLOCA_N(NativeType, paramCount);
|
185
|
+
ffiParamTypes = ALLOCA_N(ffi_type *, paramCount);
|
186
|
+
params = ALLOCA_N(FFIStorage, paramCount);
|
187
|
+
ffiValues = ALLOCA_N(void*, paramCount);
|
188
|
+
argv = ALLOCA_N(VALUE, paramCount);
|
189
|
+
|
190
|
+
for (i = 0; i < paramCount; ++i) {
|
191
|
+
VALUE entry = rb_ary_entry(parameterTypes, i);
|
192
|
+
int paramType = rbffi_Type_GetIntValue(entry);
|
193
|
+
Type* type;
|
194
|
+
Data_Get_Struct(entry, Type, type);
|
195
|
+
|
196
|
+
switch (paramType) {
|
197
|
+
case NATIVE_INT8:
|
198
|
+
case NATIVE_INT16:
|
199
|
+
case NATIVE_INT32:
|
200
|
+
case NATIVE_ENUM:
|
201
|
+
paramType = NATIVE_INT32;
|
202
|
+
ffiParamTypes[i] = &ffi_type_sint;
|
203
|
+
break;
|
204
|
+
case NATIVE_UINT8:
|
205
|
+
case NATIVE_UINT16:
|
206
|
+
case NATIVE_UINT32:
|
207
|
+
paramType = NATIVE_UINT32;
|
208
|
+
ffiParamTypes[i] = &ffi_type_uint;
|
209
|
+
break;
|
210
|
+
case NATIVE_FLOAT32:
|
211
|
+
paramType = NATIVE_FLOAT64;
|
212
|
+
ffiParamTypes[i] = &ffi_type_double;
|
213
|
+
break;
|
214
|
+
default:
|
215
|
+
ffiParamTypes[i] = type->ffiType;
|
216
|
+
break;
|
217
|
+
}
|
218
|
+
paramTypes[i] = paramType;
|
219
|
+
if (ffiParamTypes[i] == NULL) {
|
220
|
+
rb_raise(rb_eArgError, "Invalid parameter type #%x", paramType);
|
221
|
+
}
|
222
|
+
argv[i] = rb_ary_entry(parameterValues, i);
|
223
|
+
}
|
224
|
+
|
225
|
+
ffiReturnType = invoker->returnType->ffiType;
|
226
|
+
if (ffiReturnType == NULL) {
|
227
|
+
rb_raise(rb_eArgError, "Invalid return type");
|
228
|
+
}
|
229
|
+
ffiStatus = ffi_prep_cif(&cif, invoker->abi, paramCount, ffiReturnType, ffiParamTypes);
|
230
|
+
switch (ffiStatus) {
|
231
|
+
case FFI_BAD_ABI:
|
232
|
+
rb_raise(rb_eArgError, "Invalid ABI specified");
|
233
|
+
case FFI_BAD_TYPEDEF:
|
234
|
+
rb_raise(rb_eArgError, "Invalid argument type specified");
|
235
|
+
case FFI_OK:
|
236
|
+
break;
|
237
|
+
default:
|
238
|
+
rb_raise(rb_eArgError, "Unknown FFI error");
|
239
|
+
}
|
240
|
+
|
241
|
+
rbffi_SetupCallParams(paramCount, argv, -1, paramTypes, params,
|
242
|
+
ffiValues, NULL, 0, invoker->rbEnums);
|
243
|
+
|
244
|
+
return ffi_invoke(&cif, invoker->function, invoker->returnType,
|
245
|
+
ffiValues, invoker->rbReturnType, invoker->rbEnums);
|
246
|
+
}
|
247
|
+
|
248
|
+
|
249
|
+
void
|
250
|
+
rbffi_Variadic_Init(VALUE moduleFFI)
|
251
|
+
{
|
252
|
+
classVariadicInvoker = rb_define_class_under(moduleFFI, "VariadicInvoker", rb_cObject);
|
253
|
+
rb_global_variable(&classVariadicInvoker);
|
254
|
+
|
255
|
+
rb_define_alloc_func(classVariadicInvoker, variadic_allocate);
|
256
|
+
|
257
|
+
rb_define_method(classVariadicInvoker, "initialize", variadic_initialize, 4);
|
258
|
+
rb_define_method(classVariadicInvoker, "invoke", variadic_invoke, 2);
|
259
|
+
}
|
260
|
+
|
data/ext/ffi_c/compat.h
CHANGED
@@ -1,22 +1,72 @@
|
|
1
|
-
|
2
|
-
|
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
|
+
* * The name of the author or authors may not be used to endorse or promote
|
14
|
+
* products derived from this software without specific prior written permission.
|
15
|
+
*
|
16
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
17
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
18
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
19
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
20
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
21
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
22
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
23
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
24
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
25
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
26
|
+
*/
|
27
|
+
|
28
|
+
#ifndef RBFFI_COMPAT_H
|
29
|
+
#define RBFFI_COMPAT_H
|
3
30
|
|
4
31
|
#include <ruby.h>
|
5
32
|
|
6
33
|
#ifndef RARRAY_LEN
|
7
34
|
# define RARRAY_LEN(ary) RARRAY(ary)->len
|
8
35
|
#endif
|
36
|
+
|
9
37
|
#ifndef RARRAY_PTR
|
10
38
|
# define RARRAY_PTR(ary) RARRAY(ary)->ptr
|
11
39
|
#endif
|
40
|
+
|
12
41
|
#ifndef RSTRING_LEN
|
13
42
|
# define RSTRING_LEN(s) RSTRING(s)->len
|
14
43
|
#endif
|
44
|
+
|
15
45
|
#ifndef RSTRING_PTR
|
16
46
|
# define RSTRING_PTR(s) RSTRING(s)->ptr
|
17
47
|
#endif
|
48
|
+
|
18
49
|
#ifndef NUM2ULL
|
19
50
|
# define NUM2ULL(x) rb_num2ull((VALUE)x)
|
20
51
|
#endif
|
21
52
|
|
22
|
-
#
|
53
|
+
#ifndef roundup
|
54
|
+
# define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
|
55
|
+
#endif
|
56
|
+
|
57
|
+
#ifdef __GNUC__
|
58
|
+
# define likely(x) __builtin_expect((x), 1)
|
59
|
+
# define unlikely(x) __builtin_expect((x), 0)
|
60
|
+
#else
|
61
|
+
# define likely(x) (x)
|
62
|
+
# define unlikely(x) (x)
|
63
|
+
#endif
|
64
|
+
|
65
|
+
#ifndef MAX
|
66
|
+
# define MAX(a, b) ((a) < (b) ? (b) : (a))
|
67
|
+
#endif
|
68
|
+
#ifndef MIN
|
69
|
+
# define MIN(a, b) ((a) < (b) ? (a) : (b))
|
70
|
+
#endif
|
71
|
+
|
72
|
+
#endif /* RBFFI_COMPAT_H */
|
data/ext/ffi_c/extconf.rb
CHANGED
@@ -2,24 +2,23 @@
|
|
2
2
|
require 'mkmf'
|
3
3
|
require 'rbconfig'
|
4
4
|
dir_config("ffi_c")
|
5
|
-
|
6
|
-
|
7
|
-
# $CPPFLAGS << " -DMACOSX"
|
8
|
-
# find_header("ffi.h", "/usr/include/ffi")
|
9
|
-
#end
|
5
|
+
|
6
|
+
IS_MAC = Config::CONFIG['host_os'] =~ /^darwin/
|
10
7
|
have_closure_alloc = have_library("ffi", "ffi_closure_alloc", [ "ffi.h" ])
|
11
8
|
$defs.push("-DHAVE_FFI_CLOSURE_ALLOC") if have_closure_alloc
|
12
|
-
libffi_ok = have_closure_alloc
|
9
|
+
libffi_ok = have_closure_alloc && !IS_MAC
|
13
10
|
$defs << "-DHAVE_LIBFFI" if libffi_ok
|
14
11
|
$defs << "-DHAVE_EXTCONF_H" if $defs.empty? # needed so create_header works
|
15
12
|
|
13
|
+
have_func('rb_thread_blocking_region')
|
14
|
+
|
16
15
|
create_makefile("ffi_c")
|
17
16
|
create_header("extconf.h")
|
18
17
|
File.open("Makefile", "a") do |mf|
|
19
18
|
mf.puts "CPPFLAGS += -Werror -Wunused -Wformat -Wimplicit -Wreturn-type"
|
20
19
|
unless libffi_ok
|
21
20
|
mf.puts "LIBFFI_HOST=--host=#{Config::CONFIG['host_alias']}" if Config::CONFIG.has_key?("host_alias")
|
22
|
-
mf.puts "FFI_MMAP_EXEC=-DFFI_MMAP_EXEC_WRIT=#{Config::CONFIG['host_os'] =~ /
|
21
|
+
mf.puts "FFI_MMAP_EXEC=-DFFI_MMAP_EXEC_WRIT=#{Config::CONFIG['host_os'] =~ /(win32|mingw)/ ? 0 : 1}"
|
23
22
|
if Config::CONFIG['host_os'].downcase =~ /darwin/
|
24
23
|
mf.puts "include ${srcdir}/libffi.darwin.mk"
|
25
24
|
elsif Config::CONFIG['host_os'].downcase =~ /bsd/
|
data/ext/ffi_c/ffi.c
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
|
+
* * The name of the author or authors may not be used to endorse or promote
|
14
|
+
* products derived from this software without specific prior written permission.
|
15
|
+
*
|
16
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
17
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
18
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
19
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
20
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
21
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
22
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
23
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
24
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
25
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
26
|
+
*/
|
27
|
+
|
1
28
|
#include <sys/types.h>
|
2
29
|
#include <stdio.h>
|
3
30
|
#include <ruby.h>
|
@@ -10,67 +37,46 @@
|
|
10
37
|
#include "MemoryPointer.h"
|
11
38
|
#include "AutoPointer.h"
|
12
39
|
#include "Struct.h"
|
13
|
-
#include "
|
40
|
+
#include "StructByValue.h"
|
14
41
|
#include "DynamicLibrary.h"
|
15
42
|
#include "Platform.h"
|
16
43
|
#include "Types.h"
|
17
44
|
#include "LastError.h"
|
45
|
+
#include "Function.h"
|
46
|
+
#include "ClosurePool.h"
|
47
|
+
#include "MethodHandle.h"
|
48
|
+
#include "Call.h"
|
49
|
+
#include "ArrayType.h"
|
18
50
|
|
51
|
+
void Init_ffi_c(void);
|
19
52
|
|
20
|
-
|
53
|
+
VALUE rbffi_FFIModule = Qnil;
|
21
54
|
|
22
55
|
static VALUE moduleFFI = Qnil;
|
23
|
-
static VALUE typeMap = Qnil, sizeMap = Qnil;
|
24
|
-
static ID type_size_id = 0, size_id;
|
25
|
-
|
26
|
-
int
|
27
|
-
rbffi_type_size(VALUE type)
|
28
|
-
{
|
29
|
-
int t = TYPE(type);
|
30
|
-
if (t == T_FIXNUM || t == T_BIGNUM) {
|
31
|
-
return NUM2INT(type);
|
32
|
-
} else if (t == T_SYMBOL) {
|
33
|
-
/*
|
34
|
-
* Try looking up directly in the type and size maps
|
35
|
-
*/
|
36
|
-
VALUE nType;
|
37
|
-
if ((nType = rb_hash_aref(typeMap, type)) != Qnil) {
|
38
|
-
VALUE nSize = rb_hash_aref(sizeMap, nType);
|
39
|
-
if (TYPE(nSize) == T_FIXNUM) {
|
40
|
-
return FIX2INT(nSize);
|
41
|
-
}
|
42
|
-
}
|
43
|
-
// Not found - call up to the ruby version to resolve
|
44
|
-
return NUM2INT(rb_funcall2(moduleFFI, type_size_id, 1, &type));
|
45
|
-
} else {
|
46
|
-
return NUM2INT(rb_funcall2(type, size_id, 0, NULL));
|
47
|
-
}
|
48
|
-
}
|
49
56
|
|
50
57
|
void
|
51
|
-
Init_ffi_c() {
|
52
|
-
moduleFFI = rb_define_module("FFI");
|
58
|
+
Init_ffi_c(void) {
|
59
|
+
rbffi_FFIModule = moduleFFI = rb_define_module("FFI");
|
53
60
|
rb_global_variable(&moduleFFI);
|
54
|
-
rb_define_const(moduleFFI, "TypeDefs", typeMap = rb_hash_new());
|
55
|
-
rb_define_const(moduleFFI, "SizeTypes", sizeMap = rb_hash_new());
|
56
|
-
rb_global_variable(&typeMap);
|
57
|
-
rb_global_variable(&sizeMap);
|
58
|
-
type_size_id = rb_intern("type_size");
|
59
|
-
size_id = rb_intern("size");
|
60
61
|
|
62
|
+
// FFI::Type needs to be initialized before most other classes
|
61
63
|
rbffi_Type_Init(moduleFFI);
|
64
|
+
rbffi_ArrayType_Init(moduleFFI);
|
62
65
|
rbffi_LastError_Init(moduleFFI);
|
66
|
+
rbffi_Call_Init(moduleFFI);
|
67
|
+
rbffi_ClosurePool_Init(moduleFFI);
|
68
|
+
rbffi_MethodHandle_Init(moduleFFI);
|
63
69
|
rbffi_Platform_Init(moduleFFI);
|
64
70
|
rbffi_AbstractMemory_Init(moduleFFI);
|
65
71
|
rbffi_Pointer_Init(moduleFFI);
|
66
72
|
rbffi_AutoPointer_Init(moduleFFI);
|
67
|
-
|
73
|
+
rbffi_Function_Init(moduleFFI);
|
68
74
|
rbffi_MemoryPointer_Init(moduleFFI);
|
69
75
|
rbffi_Buffer_Init(moduleFFI);
|
70
|
-
|
76
|
+
rbffi_StructByValue_Init(moduleFFI);
|
71
77
|
rbffi_Struct_Init(moduleFFI);
|
72
78
|
rbffi_DynamicLibrary_Init(moduleFFI);
|
73
|
-
|
79
|
+
rbffi_Variadic_Init(moduleFFI);
|
74
80
|
rbffi_Types_Init(moduleFFI);
|
75
81
|
}
|
76
82
|
|