fiddle 1.0.9 → 1.1.2
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.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/Rakefile +12 -0
- data/ext/fiddle/closure.c +131 -33
- data/ext/fiddle/conversions.c +64 -11
- data/ext/fiddle/conversions.h +2 -0
- data/ext/fiddle/extconf.rb +15 -27
- data/ext/fiddle/fiddle.c +215 -56
- data/ext/fiddle/fiddle.h +44 -6
- data/ext/fiddle/function.c +7 -2
- data/ext/fiddle/handle.c +121 -7
- data/ext/fiddle/memory_view.c +6 -8
- data/ext/fiddle/pointer.c +57 -15
- data/ext/fiddle/win32/libffi-config.rb +5 -5
- data/fiddle.gemspec +1 -8
- data/lib/fiddle/closure.rb +25 -0
- data/lib/fiddle/cparser.rb +28 -14
- data/lib/fiddle/import.rb +2 -0
- data/lib/fiddle/pack.rb +30 -17
- data/lib/fiddle/struct.rb +71 -0
- data/lib/fiddle/value.rb +13 -15
- data/lib/fiddle/version.rb +1 -1
- data/lib/fiddle.rb +34 -1
- metadata +8 -53
- data/bin/downloader.rb +0 -331
- data/bin/extlibs.rb +0 -262
- data/ext/fiddle/extlibs +0 -13
data/ext/fiddle/handle.c
CHANGED
@@ -50,8 +50,13 @@ fiddle_handle_memsize(const void *ptr)
|
|
50
50
|
}
|
51
51
|
|
52
52
|
static const rb_data_type_t fiddle_handle_data_type = {
|
53
|
-
"fiddle/handle",
|
54
|
-
|
53
|
+
.wrap_struct_name = "fiddle/handle",
|
54
|
+
.function = {
|
55
|
+
.dmark = 0,
|
56
|
+
.dfree = fiddle_handle_free,
|
57
|
+
.dsize = fiddle_handle_memsize
|
58
|
+
},
|
59
|
+
.flags = RUBY_TYPED_WB_PROTECTED,
|
55
60
|
};
|
56
61
|
|
57
62
|
/*
|
@@ -259,7 +264,21 @@ rb_fiddle_handle_to_i(VALUE self)
|
|
259
264
|
struct dl_handle *fiddle_handle;
|
260
265
|
|
261
266
|
TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle);
|
262
|
-
return PTR2NUM(fiddle_handle);
|
267
|
+
return PTR2NUM(fiddle_handle->ptr);
|
268
|
+
}
|
269
|
+
|
270
|
+
/*
|
271
|
+
* call-seq: to_ptr
|
272
|
+
*
|
273
|
+
* Returns the Fiddle::Pointer of this handle.
|
274
|
+
*/
|
275
|
+
static VALUE
|
276
|
+
rb_fiddle_handle_to_ptr(VALUE self)
|
277
|
+
{
|
278
|
+
struct dl_handle *fiddle_handle;
|
279
|
+
|
280
|
+
TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle);
|
281
|
+
return rb_fiddle_ptr_new_wrap(fiddle_handle->ptr, 0, 0, self, 0);
|
263
282
|
}
|
264
283
|
|
265
284
|
static VALUE fiddle_handle_sym(void *handle, VALUE symbol);
|
@@ -307,8 +326,10 @@ rb_fiddle_handle_s_sym(VALUE self, VALUE sym)
|
|
307
326
|
return fiddle_handle_sym(RTLD_NEXT, sym);
|
308
327
|
}
|
309
328
|
|
310
|
-
|
311
|
-
|
329
|
+
typedef void (*fiddle_void_func)(void);
|
330
|
+
|
331
|
+
static fiddle_void_func
|
332
|
+
fiddle_handle_find_func(void *handle, VALUE symbol)
|
312
333
|
{
|
313
334
|
#if defined(HAVE_DLERROR)
|
314
335
|
const char *err;
|
@@ -316,13 +337,13 @@ fiddle_handle_sym(void *handle, VALUE symbol)
|
|
316
337
|
#else
|
317
338
|
# define CHECK_DLERROR
|
318
339
|
#endif
|
319
|
-
|
340
|
+
fiddle_void_func func;
|
320
341
|
const char *name = StringValueCStr(symbol);
|
321
342
|
|
322
343
|
#ifdef HAVE_DLERROR
|
323
344
|
dlerror();
|
324
345
|
#endif
|
325
|
-
func = (
|
346
|
+
func = (fiddle_void_func)(VALUE)dlsym(handle, name);
|
326
347
|
CHECK_DLERROR;
|
327
348
|
#if defined(FUNC_STDCALL)
|
328
349
|
if( !func ){
|
@@ -365,6 +386,53 @@ fiddle_handle_sym(void *handle, VALUE symbol)
|
|
365
386
|
xfree(name_n);
|
366
387
|
}
|
367
388
|
#endif
|
389
|
+
|
390
|
+
return func;
|
391
|
+
}
|
392
|
+
|
393
|
+
static VALUE
|
394
|
+
rb_fiddle_handle_s_sym_defined(VALUE self, VALUE sym)
|
395
|
+
{
|
396
|
+
fiddle_void_func func;
|
397
|
+
|
398
|
+
func = fiddle_handle_find_func(RTLD_NEXT, sym);
|
399
|
+
|
400
|
+
if( func ) {
|
401
|
+
return PTR2NUM(func);
|
402
|
+
}
|
403
|
+
else {
|
404
|
+
return Qnil;
|
405
|
+
}
|
406
|
+
}
|
407
|
+
|
408
|
+
static VALUE
|
409
|
+
rb_fiddle_handle_sym_defined(VALUE self, VALUE sym)
|
410
|
+
{
|
411
|
+
struct dl_handle *fiddle_handle;
|
412
|
+
fiddle_void_func func;
|
413
|
+
|
414
|
+
TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle);
|
415
|
+
if( ! fiddle_handle->open ){
|
416
|
+
rb_raise(rb_eFiddleDLError, "closed handle");
|
417
|
+
}
|
418
|
+
|
419
|
+
func = fiddle_handle_find_func(fiddle_handle->ptr, sym);
|
420
|
+
|
421
|
+
if( func ) {
|
422
|
+
return PTR2NUM(func);
|
423
|
+
}
|
424
|
+
else {
|
425
|
+
return Qnil;
|
426
|
+
}
|
427
|
+
}
|
428
|
+
|
429
|
+
static VALUE
|
430
|
+
fiddle_handle_sym(void *handle, VALUE symbol)
|
431
|
+
{
|
432
|
+
fiddle_void_func func;
|
433
|
+
|
434
|
+
func = fiddle_handle_find_func(handle, symbol);
|
435
|
+
|
368
436
|
if( !func ){
|
369
437
|
rb_raise(rb_eFiddleDLError, "unknown symbol \"%"PRIsVALUE"\"", symbol);
|
370
438
|
}
|
@@ -372,6 +440,48 @@ fiddle_handle_sym(void *handle, VALUE symbol)
|
|
372
440
|
return PTR2NUM(func);
|
373
441
|
}
|
374
442
|
|
443
|
+
/*
|
444
|
+
* call-seq: file_name
|
445
|
+
*
|
446
|
+
* Returns the file name of this handle.
|
447
|
+
*/
|
448
|
+
static VALUE
|
449
|
+
rb_fiddle_handle_file_name(VALUE self)
|
450
|
+
{
|
451
|
+
struct dl_handle *fiddle_handle;
|
452
|
+
|
453
|
+
TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle);
|
454
|
+
|
455
|
+
#if defined(HAVE_DLINFO) && defined(HAVE_CONST_RTLD_DI_LINKMAP)
|
456
|
+
{
|
457
|
+
struct link_map *lm = NULL;
|
458
|
+
int res = dlinfo(fiddle_handle->ptr, RTLD_DI_LINKMAP, &lm);
|
459
|
+
if (res == 0 && lm != NULL) {
|
460
|
+
return rb_str_new_cstr(lm->l_name);
|
461
|
+
}
|
462
|
+
else {
|
463
|
+
#if defined(HAVE_DLERROR)
|
464
|
+
rb_raise(rb_eFiddleDLError, "could not get handle file name: %s", dlerror());
|
465
|
+
#else
|
466
|
+
rb_raise(rb_eFiddleDLError, "could not get handle file name");
|
467
|
+
#endif
|
468
|
+
}
|
469
|
+
}
|
470
|
+
#elif defined(HAVE_GETMODULEFILENAME)
|
471
|
+
{
|
472
|
+
char filename[MAX_PATH];
|
473
|
+
DWORD res = GetModuleFileName(fiddle_handle->ptr, filename, MAX_PATH);
|
474
|
+
if (res == 0) {
|
475
|
+
rb_raise(rb_eFiddleDLError, "could not get handle file name: %s", dlerror());
|
476
|
+
}
|
477
|
+
return rb_str_new_cstr(filename);
|
478
|
+
}
|
479
|
+
#else
|
480
|
+
(void)fiddle_handle;
|
481
|
+
return Qnil;
|
482
|
+
#endif
|
483
|
+
}
|
484
|
+
|
375
485
|
void
|
376
486
|
Init_fiddle_handle(void)
|
377
487
|
{
|
@@ -412,6 +522,7 @@ Init_fiddle_handle(void)
|
|
412
522
|
rb_cHandle = rb_define_class_under(mFiddle, "Handle", rb_cObject);
|
413
523
|
rb_define_alloc_func(rb_cHandle, rb_fiddle_handle_s_allocate);
|
414
524
|
rb_define_singleton_method(rb_cHandle, "sym", rb_fiddle_handle_s_sym, 1);
|
525
|
+
rb_define_singleton_method(rb_cHandle, "sym_defined?", rb_fiddle_handle_s_sym_defined, 1);
|
415
526
|
rb_define_singleton_method(rb_cHandle, "[]", rb_fiddle_handle_s_sym, 1);
|
416
527
|
|
417
528
|
/* Document-const: NEXT
|
@@ -466,9 +577,12 @@ Init_fiddle_handle(void)
|
|
466
577
|
|
467
578
|
rb_define_method(rb_cHandle, "initialize", rb_fiddle_handle_initialize, -1);
|
468
579
|
rb_define_method(rb_cHandle, "to_i", rb_fiddle_handle_to_i, 0);
|
580
|
+
rb_define_method(rb_cHandle, "to_ptr", rb_fiddle_handle_to_ptr, 0);
|
469
581
|
rb_define_method(rb_cHandle, "close", rb_fiddle_handle_close, 0);
|
470
582
|
rb_define_method(rb_cHandle, "sym", rb_fiddle_handle_sym, 1);
|
471
583
|
rb_define_method(rb_cHandle, "[]", rb_fiddle_handle_sym, 1);
|
584
|
+
rb_define_method(rb_cHandle, "sym_defined?", rb_fiddle_handle_sym_defined, 1);
|
585
|
+
rb_define_method(rb_cHandle, "file_name", rb_fiddle_handle_file_name, 0);
|
472
586
|
rb_define_method(rb_cHandle, "disable_close", rb_fiddle_handle_disable_close, 0);
|
473
587
|
rb_define_method(rb_cHandle, "enable_close", rb_fiddle_handle_enable_close, 0);
|
474
588
|
rb_define_method(rb_cHandle, "close_enabled?", rb_fiddle_handle_close_enabled_p, 0);
|
data/ext/fiddle/memory_view.c
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
+
#include <fiddle.h>
|
2
|
+
|
3
|
+
#ifdef HAVE_RUBY_MEMORY_VIEW_H
|
4
|
+
|
1
5
|
#include <stdbool.h>
|
2
6
|
#include <ruby/ruby.h>
|
3
7
|
#include <ruby/encoding.h>
|
4
|
-
|
5
|
-
#ifdef HAVE_RUBY_MEMORY_VIEW_H
|
6
|
-
# include <ruby/memory_view.h>
|
7
|
-
#endif
|
8
|
+
#include <ruby/memory_view.h>
|
8
9
|
|
9
10
|
#if SIZEOF_INTPTR_T == SIZEOF_LONG_LONG
|
10
11
|
# define INTPTR2NUM LL2NUM
|
@@ -17,9 +18,6 @@
|
|
17
18
|
# define UINTPTR2NUM UINT2NUM
|
18
19
|
#endif
|
19
20
|
|
20
|
-
#include <fiddle.h>
|
21
|
-
|
22
|
-
#ifdef FIDDLE_MEMORY_VIEW
|
23
21
|
VALUE rb_cMemoryView = Qnil;
|
24
22
|
|
25
23
|
struct memview_data {
|
@@ -320,4 +318,4 @@ Init_fiddle_memory_view(void)
|
|
320
318
|
rb_define_method(rb_cMemoryView, "to_s", rb_fiddle_memview_to_s, 0);
|
321
319
|
}
|
322
320
|
|
323
|
-
#endif /*
|
321
|
+
#endif /* HAVE_RUBY_MEMORY_VIEW_H */
|
data/ext/fiddle/pointer.c
CHANGED
@@ -6,13 +6,13 @@
|
|
6
6
|
#include <ruby/ruby.h>
|
7
7
|
#include <ruby/io.h>
|
8
8
|
|
9
|
+
#include <ctype.h>
|
10
|
+
#include <fiddle.h>
|
11
|
+
|
9
12
|
#ifdef HAVE_RUBY_MEMORY_VIEW_H
|
10
13
|
# include <ruby/memory_view.h>
|
11
14
|
#endif
|
12
15
|
|
13
|
-
#include <ctype.h>
|
14
|
-
#include <fiddle.h>
|
15
|
-
|
16
16
|
#ifdef PRIsVALUE
|
17
17
|
# define RB_OBJ_CLASSNAME(obj) rb_obj_class(obj)
|
18
18
|
# define RB_OBJ_STRING(obj) (obj)
|
@@ -24,7 +24,7 @@
|
|
24
24
|
|
25
25
|
VALUE rb_cPointer;
|
26
26
|
|
27
|
-
typedef
|
27
|
+
typedef rb_fiddle_freefunc_t freefunc_t;
|
28
28
|
|
29
29
|
struct ptr_data {
|
30
30
|
void *ptr;
|
@@ -88,11 +88,16 @@ fiddle_ptr_memsize(const void *ptr)
|
|
88
88
|
}
|
89
89
|
|
90
90
|
static const rb_data_type_t fiddle_ptr_data_type = {
|
91
|
-
"fiddle/pointer",
|
92
|
-
|
91
|
+
.wrap_struct_name = "fiddle/pointer",
|
92
|
+
.function = {
|
93
|
+
.dmark = fiddle_ptr_mark,
|
94
|
+
.dfree = fiddle_ptr_free,
|
95
|
+
.dsize = fiddle_ptr_memsize,
|
96
|
+
},
|
97
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
93
98
|
};
|
94
99
|
|
95
|
-
#ifdef
|
100
|
+
#ifdef HAVE_RUBY_MEMORY_VIEW_H
|
96
101
|
static struct ptr_data *
|
97
102
|
fiddle_ptr_check_memory_view(VALUE obj)
|
98
103
|
{
|
@@ -125,7 +130,7 @@ static const rb_memory_view_entry_t fiddle_ptr_memory_view_entry = {
|
|
125
130
|
#endif
|
126
131
|
|
127
132
|
static VALUE
|
128
|
-
rb_fiddle_ptr_new2(VALUE klass, void *ptr, long size, freefunc_t func)
|
133
|
+
rb_fiddle_ptr_new2(VALUE klass, void *ptr, long size, freefunc_t func, VALUE wrap0, VALUE wrap1)
|
129
134
|
{
|
130
135
|
struct ptr_data *data;
|
131
136
|
VALUE val;
|
@@ -135,14 +140,22 @@ rb_fiddle_ptr_new2(VALUE klass, void *ptr, long size, freefunc_t func)
|
|
135
140
|
data->free = func;
|
136
141
|
data->freed = false;
|
137
142
|
data->size = size;
|
143
|
+
RB_OBJ_WRITE(val, &data->wrap[0], wrap0);
|
144
|
+
RB_OBJ_WRITE(val, &data->wrap[1], wrap1);
|
138
145
|
|
139
146
|
return val;
|
140
147
|
}
|
141
148
|
|
149
|
+
VALUE
|
150
|
+
rb_fiddle_ptr_new_wrap(void *ptr, long size, freefunc_t func, VALUE wrap0, VALUE wrap1)
|
151
|
+
{
|
152
|
+
return rb_fiddle_ptr_new2(rb_cPointer, ptr, size, func, wrap0, wrap1);
|
153
|
+
}
|
154
|
+
|
142
155
|
static VALUE
|
143
156
|
rb_fiddle_ptr_new(void *ptr, long size, freefunc_t func)
|
144
157
|
{
|
145
|
-
return rb_fiddle_ptr_new2(rb_cPointer, ptr, size, func);
|
158
|
+
return rb_fiddle_ptr_new2(rb_cPointer, ptr, size, func, 0, 0);
|
146
159
|
}
|
147
160
|
|
148
161
|
static VALUE
|
@@ -152,7 +165,7 @@ rb_fiddle_ptr_malloc(VALUE klass, long size, freefunc_t func)
|
|
152
165
|
|
153
166
|
ptr = ruby_xmalloc((size_t)size);
|
154
167
|
memset(ptr,0,(size_t)size);
|
155
|
-
return rb_fiddle_ptr_new2(klass, ptr, size, func);
|
168
|
+
return rb_fiddle_ptr_new2(klass, ptr, size, func, 0, 0);
|
156
169
|
}
|
157
170
|
|
158
171
|
static void *
|
@@ -227,8 +240,8 @@ rb_fiddle_ptr_initialize(int argc, VALUE argv[], VALUE self)
|
|
227
240
|
/* Free previous memory. Use of inappropriate initialize may cause SEGV. */
|
228
241
|
(*(data->free))(data->ptr);
|
229
242
|
}
|
230
|
-
data->wrap[0]
|
231
|
-
data->wrap[1]
|
243
|
+
RB_OBJ_WRITE(self, &data->wrap[0], wrap);
|
244
|
+
RB_OBJ_WRITE(self, &data->wrap[1], funcwrap);
|
232
245
|
data->ptr = p;
|
233
246
|
data->size = s;
|
234
247
|
data->free = f;
|
@@ -306,7 +319,7 @@ rb_fiddle_ptr_s_malloc(int argc, VALUE argv[], VALUE klass)
|
|
306
319
|
}
|
307
320
|
|
308
321
|
obj = rb_fiddle_ptr_malloc(klass, s,f);
|
309
|
-
if (wrap) RPTR_DATA(obj)->wrap[1]
|
322
|
+
if (wrap) RB_OBJ_WRITE(obj, &RPTR_DATA(obj)->wrap[1], wrap);
|
310
323
|
|
311
324
|
if (rb_block_given_p()) {
|
312
325
|
if (!f) {
|
@@ -787,10 +800,37 @@ rb_fiddle_ptr_s_to_ptr(VALUE self, VALUE val)
|
|
787
800
|
if (num == val) wrap = 0;
|
788
801
|
ptr = rb_fiddle_ptr_new(NUM2PTR(num), 0, NULL);
|
789
802
|
}
|
790
|
-
if (wrap) RPTR_DATA(ptr)->wrap[0]
|
803
|
+
if (wrap) RB_OBJ_WRITE(ptr, &RPTR_DATA(ptr)->wrap[0], wrap);
|
791
804
|
return ptr;
|
792
805
|
}
|
793
806
|
|
807
|
+
/*
|
808
|
+
* call-seq:
|
809
|
+
* Fiddle::Pointer.read(address, len) => string
|
810
|
+
*
|
811
|
+
* Or read the memory at address +address+ with length +len+ and return a
|
812
|
+
* string with that memory
|
813
|
+
*/
|
814
|
+
|
815
|
+
static VALUE
|
816
|
+
rb_fiddle_ptr_read_mem(VALUE klass, VALUE address, VALUE len)
|
817
|
+
{
|
818
|
+
return rb_str_new((char *)NUM2PTR(address), NUM2ULONG(len));
|
819
|
+
}
|
820
|
+
|
821
|
+
/*
|
822
|
+
* call-seq:
|
823
|
+
* Fiddle::Pointer.write(address, str)
|
824
|
+
*
|
825
|
+
* Write bytes in +str+ to the location pointed to by +address+.
|
826
|
+
*/
|
827
|
+
static VALUE
|
828
|
+
rb_fiddle_ptr_write_mem(VALUE klass, VALUE addr, VALUE str)
|
829
|
+
{
|
830
|
+
memcpy(NUM2PTR(addr), StringValuePtr(str), RSTRING_LEN(str));
|
831
|
+
return str;
|
832
|
+
}
|
833
|
+
|
794
834
|
void
|
795
835
|
Init_fiddle_pointer(void)
|
796
836
|
{
|
@@ -807,6 +847,8 @@ Init_fiddle_pointer(void)
|
|
807
847
|
rb_define_singleton_method(rb_cPointer, "malloc", rb_fiddle_ptr_s_malloc, -1);
|
808
848
|
rb_define_singleton_method(rb_cPointer, "to_ptr", rb_fiddle_ptr_s_to_ptr, 1);
|
809
849
|
rb_define_singleton_method(rb_cPointer, "[]", rb_fiddle_ptr_s_to_ptr, 1);
|
850
|
+
rb_define_singleton_method(rb_cPointer, "read", rb_fiddle_ptr_read_mem, 2);
|
851
|
+
rb_define_singleton_method(rb_cPointer, "write", rb_fiddle_ptr_write_mem, 2);
|
810
852
|
rb_define_method(rb_cPointer, "initialize", rb_fiddle_ptr_initialize, -1);
|
811
853
|
rb_define_method(rb_cPointer, "free=", rb_fiddle_ptr_free_set, 1);
|
812
854
|
rb_define_method(rb_cPointer, "free", rb_fiddle_ptr_free_get, 0);
|
@@ -833,7 +875,7 @@ Init_fiddle_pointer(void)
|
|
833
875
|
rb_define_method(rb_cPointer, "size", rb_fiddle_ptr_size_get, 0);
|
834
876
|
rb_define_method(rb_cPointer, "size=", rb_fiddle_ptr_size_set, 1);
|
835
877
|
|
836
|
-
#ifdef
|
878
|
+
#ifdef HAVE_RUBY_MEMORY_VIEW_H
|
837
879
|
rb_memory_view_register(rb_cPointer, &fiddle_ptr_memory_view_entry);
|
838
880
|
#endif
|
839
881
|
|
@@ -23,7 +23,7 @@ until ARGV.empty?
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
|
26
|
+
File.foreach("#{srcdir}/configure.ac") do |line|
|
27
27
|
if /^AC_INIT\((.*)\)/ =~ line
|
28
28
|
version = $1.split(/,\s*/)[1]
|
29
29
|
version.gsub!(/\A\[|\]\z/, '')
|
@@ -38,11 +38,11 @@ conf['TARGET'] = /^x64/ =~ host ? "X86_WIN64" : "X86_WIN32"
|
|
38
38
|
FileUtils.mkdir_p([builddir, "#{builddir}/include", "#{builddir}/src/x86"])
|
39
39
|
FileUtils.cp("#{basedir}/fficonfig.h", ".", preserve: true)
|
40
40
|
|
41
|
-
hdr =
|
41
|
+
hdr = File.binread("#{srcdir}/include/ffi.h.in")
|
42
42
|
hdr.gsub!(/@(\w+)@/) {conf[$1] || $&}
|
43
43
|
hdr.gsub!(/^(#if\s+)@\w+@/, '\10')
|
44
|
-
|
44
|
+
File.binwrite("#{builddir}/include/ffi.h", hdr)
|
45
45
|
|
46
|
-
mk =
|
46
|
+
mk = File.binread("#{basedir}/libffi.mk.tmpl")
|
47
47
|
mk.gsub!(/@(\w+)@/) {conf[$1] || $&}
|
48
|
-
|
48
|
+
File.binwrite("Makefile", mk)
|
data/fiddle.gemspec
CHANGED
@@ -20,15 +20,12 @@ Gem::Specification.new do |spec|
|
|
20
20
|
"LICENSE.txt",
|
21
21
|
"README.md",
|
22
22
|
"Rakefile",
|
23
|
-
"bin/downloader.rb",
|
24
|
-
"bin/extlibs.rb",
|
25
23
|
"ext/fiddle/closure.c",
|
26
24
|
"ext/fiddle/closure.h",
|
27
25
|
"ext/fiddle/conversions.c",
|
28
26
|
"ext/fiddle/conversions.h",
|
29
27
|
"ext/fiddle/depend",
|
30
28
|
"ext/fiddle/extconf.rb",
|
31
|
-
"ext/fiddle/extlibs",
|
32
29
|
"ext/fiddle/fiddle.c",
|
33
30
|
"ext/fiddle/fiddle.h",
|
34
31
|
"ext/fiddle/function.c",
|
@@ -56,11 +53,7 @@ Gem::Specification.new do |spec|
|
|
56
53
|
spec.require_paths = ["lib"]
|
57
54
|
spec.extensions = ["ext/fiddle/extconf.rb"]
|
58
55
|
|
59
|
-
spec.required_ruby_version = ">= 2.
|
60
|
-
|
61
|
-
spec.add_development_dependency "bundler"
|
62
|
-
spec.add_development_dependency "rake"
|
63
|
-
spec.add_development_dependency "rake-compiler"
|
56
|
+
spec.required_ruby_version = ">= 2.5.0"
|
64
57
|
|
65
58
|
spec.metadata["msys2_mingw_dependencies"] = "libffi"
|
66
59
|
end
|
data/lib/fiddle/closure.rb
CHANGED
@@ -1,6 +1,31 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module Fiddle
|
3
3
|
class Closure
|
4
|
+
class << self
|
5
|
+
# Create a new closure. If a block is given, the created closure
|
6
|
+
# is automatically freed after the given block is executed.
|
7
|
+
#
|
8
|
+
# The all given arguments are passed to Fiddle::Closure.new. So
|
9
|
+
# using this method without block equals to Fiddle::Closure.new.
|
10
|
+
#
|
11
|
+
# == Example
|
12
|
+
#
|
13
|
+
# Fiddle::Closure.create(TYPE_INT, [TYPE_INT]) do |closure|
|
14
|
+
# # closure is freed automatically when this block is finished.
|
15
|
+
# end
|
16
|
+
def create(*args)
|
17
|
+
if block_given?
|
18
|
+
closure = new(*args)
|
19
|
+
begin
|
20
|
+
yield(closure)
|
21
|
+
ensure
|
22
|
+
closure.free
|
23
|
+
end
|
24
|
+
else
|
25
|
+
new(*args)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
4
29
|
|
5
30
|
# the C type of the return of the FFI closure
|
6
31
|
attr_reader :ctype
|
data/lib/fiddle/cparser.rb
CHANGED
@@ -164,23 +164,35 @@ module Fiddle
|
|
164
164
|
unless Fiddle.const_defined?(:TYPE_LONG_LONG)
|
165
165
|
raise(RuntimeError, "unsupported type: #{ty}")
|
166
166
|
end
|
167
|
-
return
|
168
|
-
when /\
|
167
|
+
return TYPE_ULONG_LONG
|
168
|
+
when /\Aunsigned\s+long(?:\s+int\s+)?(?:\s+\w+)?\z/,
|
169
|
+
/\Aunsigned\s+int\s+long(?:\s+\w+)?\z/,
|
170
|
+
/\Along(?:\s+int)?\s+unsigned(?:\s+\w+)?\z/,
|
171
|
+
/\Aint\s+unsigned\s+long(?:\s+\w+)?\z/,
|
172
|
+
/\A(?:int\s+)?long\s+unsigned(?:\s+\w+)?\z/
|
173
|
+
return TYPE_ULONG
|
174
|
+
when /\A(?:signed\s+)?long(?:\s+int\s+)?(?:\s+\w+)?\z/,
|
175
|
+
/\A(?:signed\s+)?int\s+long(?:\s+\w+)?\z/,
|
176
|
+
/\Along(?:\s+int)?\s+signed(?:\s+\w+)?\z/
|
169
177
|
return TYPE_LONG
|
170
|
-
when /\Aunsigned\s+
|
171
|
-
|
178
|
+
when /\Aunsigned\s+short(?:\s+int\s+)?(?:\s+\w+)?\z/,
|
179
|
+
/\Aunsigned\s+int\s+short(?:\s+\w+)?\z/,
|
180
|
+
/\Ashort(?:\s+int)?\s+unsigned(?:\s+\w+)?\z/,
|
181
|
+
/\Aint\s+unsigned\s+short(?:\s+\w+)?\z/,
|
182
|
+
/\A(?:int\s+)?short\s+unsigned(?:\s+\w+)?\z/
|
183
|
+
return TYPE_USHORT
|
184
|
+
when /\A(?:signed\s+)?short(?:\s+int\s+)?(?:\s+\w+)?\z/,
|
185
|
+
/\A(?:signed\s+)?int\s+short(?:\s+\w+)?\z/,
|
186
|
+
/\Aint\s+(?:signed\s+)?short(?:\s+\w+)?\z/
|
187
|
+
return TYPE_SHORT
|
172
188
|
when /\A(?:signed\s+)?int(?:\s+\w+)?\z/
|
173
189
|
return TYPE_INT
|
174
190
|
when /\A(?:unsigned\s+int|uint)(?:\s+\w+)?\z/
|
175
|
-
return
|
176
|
-
when /\A(?:signed\s+)?short(?:\s+int\s+)?(?:\s+\w+)?\z/
|
177
|
-
return TYPE_SHORT
|
178
|
-
when /\Aunsigned\s+short(?:\s+int\s+)?(?:\s+\w+)?\z/
|
179
|
-
return -TYPE_SHORT
|
191
|
+
return TYPE_UINT
|
180
192
|
when /\A(?:signed\s+)?char(?:\s+\w+)?\z/
|
181
193
|
return TYPE_CHAR
|
182
194
|
when /\Aunsigned\s+char(?:\s+\w+)?\z/
|
183
|
-
return
|
195
|
+
return TYPE_UCHAR
|
184
196
|
when /\Aint8_t(?:\s+\w+)?\z/
|
185
197
|
unless Fiddle.const_defined?(:TYPE_INT8_T)
|
186
198
|
raise(RuntimeError, "unsupported type: #{ty}")
|
@@ -190,7 +202,7 @@ module Fiddle
|
|
190
202
|
unless Fiddle.const_defined?(:TYPE_INT8_T)
|
191
203
|
raise(RuntimeError, "unsupported type: #{ty}")
|
192
204
|
end
|
193
|
-
return
|
205
|
+
return TYPE_UINT8_T
|
194
206
|
when /\Aint16_t(?:\s+\w+)?\z/
|
195
207
|
unless Fiddle.const_defined?(:TYPE_INT16_T)
|
196
208
|
raise(RuntimeError, "unsupported type: #{ty}")
|
@@ -200,7 +212,7 @@ module Fiddle
|
|
200
212
|
unless Fiddle.const_defined?(:TYPE_INT16_T)
|
201
213
|
raise(RuntimeError, "unsupported type: #{ty}")
|
202
214
|
end
|
203
|
-
return
|
215
|
+
return TYPE_UINT16_T
|
204
216
|
when /\Aint32_t(?:\s+\w+)?\z/
|
205
217
|
unless Fiddle.const_defined?(:TYPE_INT32_T)
|
206
218
|
raise(RuntimeError, "unsupported type: #{ty}")
|
@@ -210,7 +222,7 @@ module Fiddle
|
|
210
222
|
unless Fiddle.const_defined?(:TYPE_INT32_T)
|
211
223
|
raise(RuntimeError, "unsupported type: #{ty}")
|
212
224
|
end
|
213
|
-
return
|
225
|
+
return TYPE_UINT32_T
|
214
226
|
when /\Aint64_t(?:\s+\w+)?\z/
|
215
227
|
unless Fiddle.const_defined?(:TYPE_INT64_T)
|
216
228
|
raise(RuntimeError, "unsupported type: #{ty}")
|
@@ -220,7 +232,7 @@ module Fiddle
|
|
220
232
|
unless Fiddle.const_defined?(:TYPE_INT64_T)
|
221
233
|
raise(RuntimeError, "unsupported type: #{ty}")
|
222
234
|
end
|
223
|
-
return
|
235
|
+
return TYPE_UINT64_T
|
224
236
|
when /\Afloat(?:\s+\w+)?\z/
|
225
237
|
return TYPE_FLOAT
|
226
238
|
when /\Adouble(?:\s+\w+)?\z/
|
@@ -235,6 +247,8 @@ module Fiddle
|
|
235
247
|
return TYPE_INTPTR_T
|
236
248
|
when /\Auintptr_t(?:\s+\w+)?\z/
|
237
249
|
return TYPE_UINTPTR_T
|
250
|
+
when "bool"
|
251
|
+
return TYPE_BOOL
|
238
252
|
when /\*/, /\[[\s\d]*\]/
|
239
253
|
return TYPE_VOIDP
|
240
254
|
when "..."
|
data/lib/fiddle/import.rb
CHANGED
data/lib/fiddle/pack.rb
CHANGED
@@ -11,25 +11,36 @@ module Fiddle
|
|
11
11
|
TYPE_LONG => ALIGN_LONG,
|
12
12
|
TYPE_FLOAT => ALIGN_FLOAT,
|
13
13
|
TYPE_DOUBLE => ALIGN_DOUBLE,
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
TYPE_UCHAR => ALIGN_CHAR,
|
15
|
+
TYPE_USHORT => ALIGN_SHORT,
|
16
|
+
TYPE_UINT => ALIGN_INT,
|
17
|
+
TYPE_ULONG => ALIGN_LONG,
|
18
|
+
TYPE_BOOL => ALIGN_BOOL,
|
18
19
|
}
|
19
20
|
|
20
21
|
PACK_MAP = {
|
21
|
-
TYPE_VOIDP => "
|
22
|
+
TYPE_VOIDP => "L!",
|
22
23
|
TYPE_CHAR => "c",
|
23
24
|
TYPE_SHORT => "s!",
|
24
25
|
TYPE_INT => "i!",
|
25
26
|
TYPE_LONG => "l!",
|
26
27
|
TYPE_FLOAT => "f",
|
27
28
|
TYPE_DOUBLE => "d",
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
TYPE_UCHAR => "C",
|
30
|
+
TYPE_USHORT => "S!",
|
31
|
+
TYPE_UINT => "I!",
|
32
|
+
TYPE_ULONG => "L!",
|
32
33
|
}
|
34
|
+
case SIZEOF_BOOL
|
35
|
+
when SIZEOF_CHAR
|
36
|
+
PACK_MAP[TYPE_BOOL] = PACK_MAP[TYPE_UCHAR]
|
37
|
+
when SIZEOF_SHORT
|
38
|
+
PACK_MAP[TYPE_BOOL] = PACK_MAP[TYPE_USHORT]
|
39
|
+
when SIZEOF_INT
|
40
|
+
PACK_MAP[TYPE_BOOL] = PACK_MAP[TYPE_UINT]
|
41
|
+
when SIZEOF_LONG
|
42
|
+
PACK_MAP[TYPE_BOOL] = PACK_MAP[TYPE_ULONG]
|
43
|
+
end
|
33
44
|
|
34
45
|
SIZE_MAP = {
|
35
46
|
TYPE_VOIDP => SIZEOF_VOIDP,
|
@@ -39,16 +50,18 @@ module Fiddle
|
|
39
50
|
TYPE_LONG => SIZEOF_LONG,
|
40
51
|
TYPE_FLOAT => SIZEOF_FLOAT,
|
41
52
|
TYPE_DOUBLE => SIZEOF_DOUBLE,
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
53
|
+
TYPE_UCHAR => SIZEOF_CHAR,
|
54
|
+
TYPE_USHORT => SIZEOF_SHORT,
|
55
|
+
TYPE_UINT => SIZEOF_INT,
|
56
|
+
TYPE_ULONG => SIZEOF_LONG,
|
57
|
+
TYPE_BOOL => SIZEOF_BOOL,
|
46
58
|
}
|
47
59
|
if defined?(TYPE_LONG_LONG)
|
48
|
-
ALIGN_MAP[TYPE_LONG_LONG] = ALIGN_MAP[
|
49
|
-
PACK_MAP[TYPE_LONG_LONG] =
|
50
|
-
|
51
|
-
|
60
|
+
ALIGN_MAP[TYPE_LONG_LONG] = ALIGN_MAP[TYPE_ULONG_LONG] = ALIGN_LONG_LONG
|
61
|
+
PACK_MAP[TYPE_LONG_LONG] = "q"
|
62
|
+
PACK_MAP[TYPE_ULONG_LONG] = "Q"
|
63
|
+
SIZE_MAP[TYPE_LONG_LONG] = SIZE_MAP[TYPE_ULONG_LONG] = SIZEOF_LONG_LONG
|
64
|
+
PACK_MAP[TYPE_VOIDP] = "Q" if SIZEOF_LONG_LONG == SIZEOF_VOIDP
|
52
65
|
end
|
53
66
|
|
54
67
|
def align(addr, align)
|