ffi 1.0.9 → 1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ffi might be problematic. Click here for more details.
- data/Rakefile +4 -4
- data/ext/ffi_c/AbstractMemory.c +367 -14
- data/ext/ffi_c/AbstractMemory.h +4 -0
- data/ext/ffi_c/ArrayType.c +28 -0
- data/ext/ffi_c/Buffer.c +101 -25
- data/ext/ffi_c/Call.c +8 -5
- data/ext/ffi_c/ClosurePool.c +9 -8
- data/ext/ffi_c/DataConverter.c +29 -0
- data/ext/ffi_c/DynamicLibrary.c +64 -1
- data/ext/ffi_c/Function.c +111 -10
- data/ext/ffi_c/FunctionInfo.c +13 -1
- data/ext/ffi_c/LastError.c +16 -0
- data/ext/ffi_c/MappedType.c +22 -0
- data/ext/ffi_c/MemoryPointer.c +11 -1
- data/ext/ffi_c/MethodHandle.c +18 -11
- data/ext/ffi_c/Platform.c +9 -3
- data/ext/ffi_c/Pointer.c +98 -0
- data/ext/ffi_c/Struct.c +4 -4
- data/ext/ffi_c/Struct.h +2 -1
- data/ext/ffi_c/StructLayout.c +2 -2
- data/ext/ffi_c/Thread.c +124 -1
- data/ext/ffi_c/Type.c +108 -17
- data/ext/ffi_c/Types.c +9 -2
- data/ext/ffi_c/Variadic.c +5 -4
- data/ext/ffi_c/compat.h +8 -0
- data/ext/ffi_c/endian.h +7 -1
- data/ext/ffi_c/extconf.rb +46 -35
- data/ext/ffi_c/ffi.c +5 -0
- data/ext/ffi_c/libffi.darwin.mk +15 -15
- data/ext/ffi_c/libffi.gnu.mk +3 -3
- data/ext/ffi_c/libffi.mk +4 -4
- data/lib/ffi.rb +13 -9
- data/lib/ffi/autopointer.rb +88 -26
- data/lib/ffi/enum.rb +42 -0
- data/lib/ffi/errno.rb +6 -1
- data/lib/ffi/ffi.rb +1 -0
- data/lib/ffi/io.rb +13 -2
- data/lib/ffi/library.rb +212 -19
- data/lib/ffi/memorypointer.rb +1 -33
- data/lib/ffi/platform.rb +23 -7
- data/lib/ffi/platform/i386-freebsd/types.conf +152 -0
- data/lib/ffi/platform/i386-netbsd/types.conf +126 -0
- data/lib/ffi/platform/x86_64-freebsd/types.conf +126 -0
- data/lib/ffi/platform/x86_64-netbsd/types.conf +126 -0
- data/lib/ffi/pointer.rb +44 -0
- data/lib/ffi/struct.rb +1 -1
- data/lib/ffi/struct_layout_builder.rb +2 -1
- data/lib/ffi/tools/const_generator.rb +72 -17
- data/lib/ffi/types.rb +21 -1
- data/spec/ffi/rbx/memory_pointer_spec.rb +4 -2
- data/spec/ffi/struct_spec.rb +10 -0
- data/spec/ffi/typedef_spec.rb +11 -0
- data/tasks/extension.rake +0 -1
- data/tasks/gem.rake +0 -1
- data/tasks/yard.rake +11 -0
- metadata +15 -8
data/ext/ffi_c/DynamicLibrary.c
CHANGED
@@ -22,6 +22,7 @@
|
|
22
22
|
#include <stdio.h>
|
23
23
|
#include <stdint.h>
|
24
24
|
#if defined(_WIN32) || defined(__WIN32__)
|
25
|
+
# define _WINSOCKAPI_
|
25
26
|
# include <windows.h>
|
26
27
|
#else
|
27
28
|
# include <dlfcn.h>
|
@@ -75,12 +76,28 @@ library_allocate(VALUE klass)
|
|
75
76
|
return Data_Make_Struct(klass, Library, NULL, library_free, library);
|
76
77
|
}
|
77
78
|
|
79
|
+
/*
|
80
|
+
* call-seq: DynamicLibrary.open(libname, libflags)
|
81
|
+
* @param libname (see #initialize)
|
82
|
+
* @param libflags (see #initialize)
|
83
|
+
* @return [FFI::DynamicLibrary]
|
84
|
+
* @raise {LoadError} if +libname+ cannot be opened
|
85
|
+
* Open a library.
|
86
|
+
*/
|
78
87
|
static VALUE
|
79
88
|
library_open(VALUE klass, VALUE libname, VALUE libflags)
|
80
89
|
{
|
81
90
|
return library_initialize(library_allocate(klass), libname, libflags);
|
82
91
|
}
|
83
92
|
|
93
|
+
/*
|
94
|
+
* call-seq: initialize(libname, libflags)
|
95
|
+
* @param [String] libname name of library to open
|
96
|
+
* @param [Fixnum] libflags flags for library to open
|
97
|
+
* @return [FFI::DynamicLibrary]
|
98
|
+
* @raise {LoadError} if +libname+ cannot be opened
|
99
|
+
* A new DynamicLibrary instance.
|
100
|
+
*/
|
84
101
|
static VALUE
|
85
102
|
library_initialize(VALUE self, VALUE libname, VALUE libflags)
|
86
103
|
{
|
@@ -117,6 +134,10 @@ library_dlsym(VALUE self, VALUE name)
|
|
117
134
|
return address != NULL ? symbol_new(self, address, name) : Qnil;
|
118
135
|
}
|
119
136
|
|
137
|
+
/*
|
138
|
+
* call-seq: last_error
|
139
|
+
* @return [String] library's last error string
|
140
|
+
*/
|
120
141
|
static VALUE
|
121
142
|
library_dlerror(VALUE self)
|
122
143
|
{
|
@@ -144,7 +165,7 @@ dl_open(const char* name, int flags)
|
|
144
165
|
if (name == NULL) {
|
145
166
|
return GetModuleHandle(NULL);
|
146
167
|
} else {
|
147
|
-
return
|
168
|
+
return LoadLibraryExA(name, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
|
148
169
|
}
|
149
170
|
}
|
150
171
|
|
@@ -169,6 +190,12 @@ symbol_allocate(VALUE klass)
|
|
169
190
|
}
|
170
191
|
|
171
192
|
|
193
|
+
/*
|
194
|
+
* call-seq: initialize_copy(other)
|
195
|
+
* @param [Object] other
|
196
|
+
* @return [nil]
|
197
|
+
* DO NOT CALL THIS METHOD
|
198
|
+
*/
|
172
199
|
static VALUE
|
173
200
|
symbol_initialize_copy(VALUE self, VALUE other)
|
174
201
|
{
|
@@ -199,6 +226,11 @@ symbol_mark(LibrarySymbol* sym)
|
|
199
226
|
rb_gc_mark(sym->name);
|
200
227
|
}
|
201
228
|
|
229
|
+
/*
|
230
|
+
* call-seq: inspect
|
231
|
+
* @return [String]
|
232
|
+
* Inspect.
|
233
|
+
*/
|
202
234
|
static VALUE
|
203
235
|
symbol_inspect(VALUE self)
|
204
236
|
{
|
@@ -214,18 +246,49 @@ symbol_inspect(VALUE self)
|
|
214
246
|
void
|
215
247
|
rbffi_DynamicLibrary_Init(VALUE moduleFFI)
|
216
248
|
{
|
249
|
+
/*
|
250
|
+
* Document-class: FFI::DynamicLibrary
|
251
|
+
*/
|
217
252
|
LibraryClass = rb_define_class_under(moduleFFI, "DynamicLibrary", rb_cObject);
|
218
253
|
rb_global_variable(&LibraryClass);
|
254
|
+
/*
|
255
|
+
* Document-class: FFI::DynamicLibrary::Symbol < FFI::Pointer
|
256
|
+
*
|
257
|
+
* An instance of this class represents a library symbol. It may be a {Pointer pointer} to
|
258
|
+
* a function or to a variable.
|
259
|
+
*/
|
219
260
|
SymbolClass = rb_define_class_under(LibraryClass, "Symbol", rbffi_PointerClass);
|
220
261
|
rb_global_variable(&SymbolClass);
|
221
262
|
|
263
|
+
/*
|
264
|
+
* Document-const: FFI::NativeLibrary
|
265
|
+
* Backward compatibility for FFI::DynamicLibrary
|
266
|
+
*/
|
222
267
|
rb_define_const(moduleFFI, "NativeLibrary", LibraryClass); // backwards compat library
|
223
268
|
rb_define_alloc_func(LibraryClass, library_allocate);
|
224
269
|
rb_define_singleton_method(LibraryClass, "open", library_open, 2);
|
225
270
|
rb_define_singleton_method(LibraryClass, "last_error", library_dlerror, 0);
|
226
271
|
rb_define_method(LibraryClass, "initialize", library_initialize, 2);
|
272
|
+
/*
|
273
|
+
* Document-method: find_symbol
|
274
|
+
* call-seq: find_symbol(name)
|
275
|
+
* @param [String] name library symbol's name
|
276
|
+
* @return [FFI::DynamicLibrary::Symbol] library symbol
|
277
|
+
*/
|
227
278
|
rb_define_method(LibraryClass, "find_symbol", library_dlsym, 1);
|
279
|
+
/*
|
280
|
+
* Document-method: find_function
|
281
|
+
* call-seq: find_function(name)
|
282
|
+
* @param [String] name library function's name
|
283
|
+
* @return [FFI::DynamicLibrary::Symbol] library function symbol
|
284
|
+
*/
|
228
285
|
rb_define_method(LibraryClass, "find_function", library_dlsym, 1);
|
286
|
+
/*
|
287
|
+
* Document-method: find_variable
|
288
|
+
* call-seq: find_variable(name)
|
289
|
+
* @param [String] name library variable's name
|
290
|
+
* @return [FFI::DynamicLibrary::Symbol] library variable symbol
|
291
|
+
*/
|
229
292
|
rb_define_method(LibraryClass, "find_variable", library_dlsym, 1);
|
230
293
|
rb_define_method(LibraryClass, "last_error", library_dlerror, 0);
|
231
294
|
rb_define_attr(LibraryClass, "name", 1, 0);
|
data/ext/ffi_c/Function.c
CHANGED
@@ -69,9 +69,7 @@ static void callback_invoke(ffi_cif* cif, void* retval, void** parameters, void*
|
|
69
69
|
static bool callback_prep(void* ctx, void* code, Closure* closure, char* errmsg, size_t errmsgsize);
|
70
70
|
static void* callback_with_gvl(void* data);
|
71
71
|
|
72
|
-
#
|
73
|
-
# define DEFER_ASYNC_CALLBACK 1
|
74
|
-
#endif
|
72
|
+
#define DEFER_ASYNC_CALLBACK 1
|
75
73
|
|
76
74
|
|
77
75
|
#if defined(DEFER_ASYNC_CALLBACK)
|
@@ -117,8 +115,11 @@ static struct gvl_callback* async_cb_list = NULL;
|
|
117
115
|
static int async_cb_pipe[2];
|
118
116
|
# endif
|
119
117
|
# else
|
120
|
-
static HANDLE async_cb_cond;
|
121
|
-
static CRITICAL_SECTION async_cb_lock;
|
118
|
+
static HANDLE async_cb_cond;
|
119
|
+
static CRITICAL_SECTION async_cb_lock;
|
120
|
+
# if !defined(HAVE_RB_THREAD_BLOCKING_REGION)
|
121
|
+
static int async_cb_pipe[2];
|
122
|
+
# endif
|
122
123
|
# endif
|
123
124
|
#endif
|
124
125
|
|
@@ -162,6 +163,20 @@ function_free(Function *fn)
|
|
162
163
|
xfree(fn);
|
163
164
|
}
|
164
165
|
|
166
|
+
/*
|
167
|
+
* @param [Type, Symbol] return_type return type for the function
|
168
|
+
* @param [Array<Type, Symbol>] param_types array of parameters types
|
169
|
+
* @param [Hash] options see {FFI::FunctionType} for available options
|
170
|
+
* @return [self]
|
171
|
+
* A new Function instance.
|
172
|
+
*
|
173
|
+
* Define a function from a Proc or a block.
|
174
|
+
*
|
175
|
+
* @overload initialize(return_type, param_types, options = {}) { |i| ... }
|
176
|
+
* @yieldparam i parameters for the function
|
177
|
+
* @overload initialize(return_type, param_types, proc, options = {})
|
178
|
+
* @param [Proc] proc
|
179
|
+
*/
|
165
180
|
static VALUE
|
166
181
|
function_initialize(int argc, VALUE* argv, VALUE self)
|
167
182
|
{
|
@@ -202,6 +217,11 @@ function_initialize(int argc, VALUE* argv, VALUE self)
|
|
202
217
|
return self;
|
203
218
|
}
|
204
219
|
|
220
|
+
/*
|
221
|
+
* call-seq: initialize_copy(other)
|
222
|
+
* @return [nil]
|
223
|
+
* DO NOT CALL THIS METHOD
|
224
|
+
*/
|
205
225
|
static VALUE
|
206
226
|
function_initialize_copy(VALUE self, VALUE other)
|
207
227
|
{
|
@@ -277,7 +297,9 @@ function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc)
|
|
277
297
|
|
278
298
|
#if defined(DEFER_ASYNC_CALLBACK)
|
279
299
|
if (async_cb_thread == Qnil) {
|
280
|
-
#if !defined(HAVE_RB_THREAD_BLOCKING_REGION)
|
300
|
+
#if !defined(HAVE_RB_THREAD_BLOCKING_REGION) && defined(_WIN32)
|
301
|
+
_pipe(async_cb_pipe, 1024, O_BINARY);
|
302
|
+
#elif !defined(HAVE_RB_THREAD_BLOCKING_REGION)
|
281
303
|
pipe(async_cb_pipe);
|
282
304
|
fcntl(async_cb_pipe[0], F_SETFL, fcntl(async_cb_pipe[0], F_GETFL) | O_NONBLOCK);
|
283
305
|
fcntl(async_cb_pipe[1], F_SETFL, fcntl(async_cb_pipe[1], F_GETFL) | O_NONBLOCK);
|
@@ -303,6 +325,12 @@ function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc)
|
|
303
325
|
return self;
|
304
326
|
}
|
305
327
|
|
328
|
+
/*
|
329
|
+
* call-seq: call(*args)
|
330
|
+
* @param [Array] args function arguments
|
331
|
+
* @return [FFI::Type]
|
332
|
+
* Call the function
|
333
|
+
*/
|
306
334
|
static VALUE
|
307
335
|
function_call(int argc, VALUE* argv, VALUE self)
|
308
336
|
{
|
@@ -313,6 +341,13 @@ function_call(int argc, VALUE* argv, VALUE self)
|
|
313
341
|
return (*fn->info->invoke)(argc, argv, fn->base.memory.address, fn->info);
|
314
342
|
}
|
315
343
|
|
344
|
+
/*
|
345
|
+
* call-seq: attach(m, name)
|
346
|
+
* @param [Module] m
|
347
|
+
* @param [String] name
|
348
|
+
* @return [self]
|
349
|
+
* Attach a Function to the Module +m+ as +name+.
|
350
|
+
*/
|
316
351
|
static VALUE
|
317
352
|
function_attach(VALUE self, VALUE module, VALUE name)
|
318
353
|
{
|
@@ -351,6 +386,12 @@ function_attach(VALUE self, VALUE module, VALUE name)
|
|
351
386
|
return self;
|
352
387
|
}
|
353
388
|
|
389
|
+
/*
|
390
|
+
* call-seq: autorelease = autorelease
|
391
|
+
* @param [Boolean] autorelease
|
392
|
+
* @return [self]
|
393
|
+
* Set +autorelease+ attribute (See {Pointer}).
|
394
|
+
*/
|
354
395
|
static VALUE
|
355
396
|
function_set_autorelease(VALUE self, VALUE autorelease)
|
356
397
|
{
|
@@ -373,6 +414,11 @@ function_autorelease_p(VALUE self)
|
|
373
414
|
return fn->autorelease ? Qtrue : Qfalse;
|
374
415
|
}
|
375
416
|
|
417
|
+
/*
|
418
|
+
* call-seq: free
|
419
|
+
* @return [self]
|
420
|
+
* Free memory allocated by Function.
|
421
|
+
*/
|
376
422
|
static VALUE
|
377
423
|
function_release(VALUE self)
|
378
424
|
{
|
@@ -441,16 +487,27 @@ callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data)
|
|
441
487
|
|
442
488
|
#elif defined(DEFER_ASYNC_CALLBACK) && defined(_WIN32)
|
443
489
|
} else {
|
490
|
+
bool empty = false;
|
491
|
+
|
444
492
|
cb.async_event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
445
|
-
|
493
|
+
|
446
494
|
// Now signal the async callback thread
|
447
495
|
EnterCriticalSection(&async_cb_lock);
|
496
|
+
empty = async_cb_list == NULL;
|
448
497
|
cb.next = async_cb_list;
|
449
498
|
async_cb_list = &cb;
|
450
499
|
LeaveCriticalSection(&async_cb_lock);
|
451
500
|
|
501
|
+
#if !defined(HAVE_RB_THREAD_BLOCKING_REGION)
|
502
|
+
// Only signal if the list was empty
|
503
|
+
if (empty) {
|
504
|
+
char c;
|
505
|
+
write(async_cb_pipe[1], &c, 1);
|
506
|
+
}
|
507
|
+
#else
|
452
508
|
SetEvent(async_cb_cond);
|
453
|
-
|
509
|
+
#endif
|
510
|
+
|
454
511
|
// Wait for the thread executing the ruby callback to signal it is done
|
455
512
|
WaitForSingleObject(cb.async_event, INFINITE);
|
456
513
|
CloseHandle(cb.async_event);
|
@@ -481,10 +538,39 @@ async_cb_event(void* unused)
|
|
481
538
|
rb_thread_create(async_cb_call, w.cb);
|
482
539
|
}
|
483
540
|
}
|
484
|
-
|
541
|
+
|
485
542
|
return Qnil;
|
486
543
|
}
|
487
544
|
|
545
|
+
#elif defined(_WIN32)
|
546
|
+
static VALUE
|
547
|
+
async_cb_event(void* unused)
|
548
|
+
{
|
549
|
+
while (true) {
|
550
|
+
struct gvl_callback* cb;
|
551
|
+
char buf[64];
|
552
|
+
fd_set rfds;
|
553
|
+
|
554
|
+
FD_ZERO(&rfds);
|
555
|
+
FD_SET(async_cb_pipe[0], &rfds);
|
556
|
+
rb_thread_select(async_cb_pipe[0] + 1, &rfds, NULL, NULL, NULL);
|
557
|
+
read(async_cb_pipe[0], buf, sizeof(buf));
|
558
|
+
|
559
|
+
EnterCriticalSection(&async_cb_lock);
|
560
|
+
cb = async_cb_list;
|
561
|
+
async_cb_list = NULL;
|
562
|
+
LeaveCriticalSection(&async_cb_lock);
|
563
|
+
|
564
|
+
while (cb != NULL) {
|
565
|
+
struct gvl_callback* next = cb->next;
|
566
|
+
// Start up a new ruby thread to run the ruby callback
|
567
|
+
rb_thread_create(async_cb_call, cb);
|
568
|
+
cb = next;
|
569
|
+
}
|
570
|
+
}
|
571
|
+
|
572
|
+
return Qnil;
|
573
|
+
}
|
488
574
|
#else
|
489
575
|
static VALUE
|
490
576
|
async_cb_event(void* unused)
|
@@ -709,6 +795,7 @@ callback_with_gvl(void* data)
|
|
709
795
|
}
|
710
796
|
|
711
797
|
rbReturnValue = rb_funcall2(fn->rbProc, id_call, cbInfo->parameterCount, rbParams);
|
798
|
+
RB_GC_GUARD_PTR(rbParams);
|
712
799
|
|
713
800
|
if (unlikely(returnType->nativeType == NATIVE_MAPPED)) {
|
714
801
|
VALUE values[] = { rbReturnValue, Qnil };
|
@@ -822,6 +909,9 @@ void
|
|
822
909
|
rbffi_Function_Init(VALUE moduleFFI)
|
823
910
|
{
|
824
911
|
rbffi_FunctionInfo_Init(moduleFFI);
|
912
|
+
/*
|
913
|
+
* Document-class: FFI::Function < FFI::Pointer
|
914
|
+
*/
|
825
915
|
rbffi_FunctionClass = rb_define_class_under(moduleFFI, "Function", rbffi_PointerClass);
|
826
916
|
|
827
917
|
rb_global_variable(&rbffi_FunctionClass);
|
@@ -833,7 +923,18 @@ rbffi_Function_Init(VALUE moduleFFI)
|
|
833
923
|
rb_define_method(rbffi_FunctionClass, "attach", function_attach, 2);
|
834
924
|
rb_define_method(rbffi_FunctionClass, "free", function_release, 0);
|
835
925
|
rb_define_method(rbffi_FunctionClass, "autorelease=", function_set_autorelease, 1);
|
926
|
+
/*
|
927
|
+
* call-seq: autorelease
|
928
|
+
* @return [Boolean]
|
929
|
+
* Get +autorelease+ attribute.
|
930
|
+
* Synonymous for {#autorelease?}.
|
931
|
+
*/
|
836
932
|
rb_define_method(rbffi_FunctionClass, "autorelease", function_autorelease_p, 0);
|
933
|
+
/*
|
934
|
+
* call-seq: autorelease?
|
935
|
+
* @return [Boolean] +autorelease+ attribute
|
936
|
+
* Get +autorelease+ attribute.
|
937
|
+
*/
|
837
938
|
rb_define_method(rbffi_FunctionClass, "autorelease?", function_autorelease_p, 0);
|
838
939
|
|
839
940
|
id_call = rb_intern("call");
|
@@ -841,7 +942,7 @@ rbffi_Function_Init(VALUE moduleFFI)
|
|
841
942
|
id_cb_ref = rb_intern("@__ffi_callback__");
|
842
943
|
id_to_native = rb_intern("to_native");
|
843
944
|
id_from_native = rb_intern("from_native");
|
844
|
-
#if defined(_WIN32)
|
945
|
+
#if defined(_WIN32)
|
845
946
|
InitializeCriticalSection(&async_cb_lock);
|
846
947
|
async_cb_cond = CreateEvent(NULL, FALSE, FALSE, NULL);
|
847
948
|
#endif
|
data/ext/ffi_c/FunctionInfo.c
CHANGED
@@ -105,7 +105,7 @@ fntype_initialize(int argc, VALUE* argv, VALUE self)
|
|
105
105
|
Check_Type(rbParamTypes, T_ARRAY);
|
106
106
|
|
107
107
|
Data_Get_Struct(self, FunctionType, fnInfo);
|
108
|
-
fnInfo->parameterCount = RARRAY_LEN(rbParamTypes);
|
108
|
+
fnInfo->parameterCount = (int) RARRAY_LEN(rbParamTypes);
|
109
109
|
fnInfo->parameterTypes = xcalloc(fnInfo->parameterCount, sizeof(*fnInfo->parameterTypes));
|
110
110
|
fnInfo->ffiParameterTypes = xcalloc(fnInfo->parameterCount, sizeof(ffi_type *));
|
111
111
|
fnInfo->nativeParameterTypes = xcalloc(fnInfo->parameterCount, sizeof(*fnInfo->nativeParameterTypes));
|
@@ -201,10 +201,22 @@ fntype_param_types(VALUE self)
|
|
201
201
|
void
|
202
202
|
rbffi_FunctionInfo_Init(VALUE moduleFFI)
|
203
203
|
{
|
204
|
+
/*
|
205
|
+
* Document-class: FFI::FunctionType < FFI::Type
|
206
|
+
*/
|
204
207
|
rbffi_FunctionTypeClass = rb_define_class_under(moduleFFI, "FunctionType", rbffi_TypeClass);
|
205
208
|
rb_global_variable(&rbffi_FunctionTypeClass);
|
209
|
+
/*
|
210
|
+
* Document-const: FFI::CallbackInfo = FFI::FunctionType
|
211
|
+
*/
|
206
212
|
rb_define_const(moduleFFI, "CallbackInfo", rbffi_FunctionTypeClass);
|
213
|
+
/*
|
214
|
+
* Document-const: FFI::FunctionInfo = FFI::FunctionType
|
215
|
+
*/
|
207
216
|
rb_define_const(moduleFFI, "FunctionInfo", rbffi_FunctionTypeClass);
|
217
|
+
/*
|
218
|
+
* Document-const: FFI::Type::Function = FFI::FunctionType
|
219
|
+
*/
|
208
220
|
rb_define_const(rbffi_TypeClass, "Function", rbffi_FunctionTypeClass);
|
209
221
|
|
210
222
|
rb_define_alloc_func(rbffi_FunctionTypeClass, fntype_allocate);
|
data/ext/ffi_c/LastError.c
CHANGED
@@ -99,6 +99,11 @@ thread_data_get()
|
|
99
99
|
#endif
|
100
100
|
|
101
101
|
|
102
|
+
/*
|
103
|
+
* call-seq: error
|
104
|
+
* @return [Numeric]
|
105
|
+
* Get +errno+ value.
|
106
|
+
*/
|
102
107
|
static VALUE
|
103
108
|
get_last_error(VALUE self)
|
104
109
|
{
|
@@ -106,6 +111,12 @@ get_last_error(VALUE self)
|
|
106
111
|
}
|
107
112
|
|
108
113
|
|
114
|
+
/*
|
115
|
+
* call-seq: error(error)
|
116
|
+
* @param [Numeric] error
|
117
|
+
* @return [nil]
|
118
|
+
* Set +errno+ value.
|
119
|
+
*/
|
109
120
|
static VALUE
|
110
121
|
set_last_error(VALUE self, VALUE error)
|
111
122
|
{
|
@@ -138,6 +149,11 @@ rbffi_save_errno(void)
|
|
138
149
|
void
|
139
150
|
rbffi_LastError_Init(VALUE moduleFFI)
|
140
151
|
{
|
152
|
+
/*
|
153
|
+
* Document-module: FFI::LastError
|
154
|
+
* This module defines a couple of method to set and get +errno+
|
155
|
+
* for current thread.
|
156
|
+
*/
|
141
157
|
VALUE moduleError = rb_define_module_under(moduleFFI, "LastError");
|
142
158
|
|
143
159
|
rb_define_module_function(moduleError, "error", get_last_error, 0);
|
data/ext/ffi_c/MappedType.c
CHANGED
@@ -50,6 +50,12 @@ mapped_allocate(VALUE klass)
|
|
50
50
|
return obj;
|
51
51
|
}
|
52
52
|
|
53
|
+
/*
|
54
|
+
* call-seq: initialize(converter)
|
55
|
+
* @param [#native_type, #to_native, #from_native] converter +converter+ must respond to
|
56
|
+
* all these methods
|
57
|
+
* @return [self]
|
58
|
+
*/
|
53
59
|
static VALUE
|
54
60
|
mapped_initialize(VALUE self, VALUE rbConverter)
|
55
61
|
{
|
@@ -88,6 +94,11 @@ mapped_mark(MappedType* m)
|
|
88
94
|
rb_gc_mark(m->rbConverter);
|
89
95
|
}
|
90
96
|
|
97
|
+
/*
|
98
|
+
* call-seq: mapped_type.native_type
|
99
|
+
* @return [Type]
|
100
|
+
* Get native type of mapped type.
|
101
|
+
*/
|
91
102
|
static VALUE
|
92
103
|
mapped_native_type(VALUE self)
|
93
104
|
{
|
@@ -97,6 +108,10 @@ mapped_native_type(VALUE self)
|
|
97
108
|
return m->rbType;
|
98
109
|
}
|
99
110
|
|
111
|
+
/*
|
112
|
+
* call-seq: mapped_type.to_native(*args)
|
113
|
+
* @param args depends on {FFI::DataConverter} used to initialize +self+
|
114
|
+
*/
|
100
115
|
static VALUE
|
101
116
|
mapped_to_native(int argc, VALUE* argv, VALUE self)
|
102
117
|
{
|
@@ -107,6 +122,10 @@ mapped_to_native(int argc, VALUE* argv, VALUE self)
|
|
107
122
|
return rb_funcall2(m->rbConverter, id_to_native, argc, argv);
|
108
123
|
}
|
109
124
|
|
125
|
+
/*
|
126
|
+
* call-seq: mapped_type.from_native(*args)
|
127
|
+
* @param args depends on {FFI::DataConverter} used to initialize +self+
|
128
|
+
*/
|
110
129
|
static VALUE
|
111
130
|
mapped_from_native(int argc, VALUE* argv, VALUE self)
|
112
131
|
{
|
@@ -121,6 +140,9 @@ void
|
|
121
140
|
rbffi_MappedType_Init(VALUE moduleFFI)
|
122
141
|
{
|
123
142
|
|
143
|
+
/*
|
144
|
+
* Document-class: FFI::Type::Mapped
|
145
|
+
*/
|
124
146
|
rbffi_MappedTypeClass = rb_define_class_under(rbffi_TypeClass, "Mapped", rbffi_TypeClass);
|
125
147
|
|
126
148
|
rb_global_variable(&rbffi_MappedTypeClass);
|