rubysl-dl 0.0.1 → 1.0.0
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 +7 -0
- data/.gitignore +0 -1
- data/.travis.yml +8 -0
- data/README.md +2 -2
- data/Rakefile +0 -1
- data/ext/rubysl/dl/depend +46 -0
- data/ext/rubysl/dl/dl.c +742 -0
- data/ext/rubysl/dl/dl.def +59 -0
- data/ext/rubysl/dl/dl.h +313 -0
- data/ext/rubysl/dl/extconf.rb +193 -0
- data/ext/rubysl/dl/h2rb +500 -0
- data/ext/rubysl/dl/handle.c +215 -0
- data/ext/rubysl/dl/install.rb +49 -0
- data/ext/rubysl/dl/lib/dl/import.rb +225 -0
- data/ext/rubysl/dl/lib/dl/struct.rb +149 -0
- data/ext/rubysl/dl/lib/dl/types.rb +245 -0
- data/ext/rubysl/dl/lib/dl/win32.rb +25 -0
- data/ext/rubysl/dl/mkcall.rb +69 -0
- data/ext/rubysl/dl/mkcallback.rb +63 -0
- data/ext/rubysl/dl/mkcbtable.rb +25 -0
- data/ext/rubysl/dl/ptr.c +1062 -0
- data/ext/rubysl/dl/sample/c++sample.C +35 -0
- data/ext/rubysl/dl/sample/c++sample.rb +60 -0
- data/ext/rubysl/dl/sample/drives.rb +70 -0
- data/ext/rubysl/dl/sample/getch.rb +5 -0
- data/ext/rubysl/dl/sample/libc.rb +69 -0
- data/ext/rubysl/dl/sample/msgbox.rb +19 -0
- data/ext/rubysl/dl/sample/msgbox2.rb +18 -0
- data/ext/rubysl/dl/sample/stream.rb +87 -0
- data/ext/rubysl/dl/sym.c +993 -0
- data/ext/rubysl/dl/test/libtest.def +28 -0
- data/ext/rubysl/dl/test/test.c +247 -0
- data/ext/rubysl/dl/test/test.rb +306 -0
- data/ext/rubysl/dl/type.rb +115 -0
- data/lib/dl.rb +1 -0
- data/lib/rubysl/dl.rb +2 -0
- data/lib/rubysl/dl/version.rb +5 -0
- data/rubysl-dl.gemspec +20 -18
- metadata +109 -87
- data/lib/rubysl-dl.rb +0 -7
- data/lib/rubysl-dl/version.rb +0 -5
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d2c2566899a33959bd4bf3016f2aef1c68866fea
|
4
|
+
data.tar.gz: 46537741f8cde07062b521fa22e03b298e0aa0ef
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fe5bd99974ce25b12954e0cf4c434760bb9afaa0819ad7c0305091d9446c8cee61b940be1cbd48b4d81433a7cb85fa153b56b35adb33c0ab9446f5dec7d4b080
|
7
|
+
data.tar.gz: aaff5817f2ab9fb93e6e628fef52e5641b11c4cfd1d10cede46018834d1c43ec62cac9b66a95181c6bdbbf33444fbfc3436fe326f79e18c95269f2bbc42fca52
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# Rubysl::Dl
|
2
2
|
|
3
3
|
TODO: Write a gem description
|
4
4
|
|
@@ -24,6 +24,6 @@ TODO: Write usage instructions here
|
|
24
24
|
|
25
25
|
1. Fork it
|
26
26
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
-
3. Commit your changes (`git commit -am '
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
28
|
4. Push to the branch (`git push origin my-new-feature`)
|
29
29
|
5. Create new Pull Request
|
data/Rakefile
CHANGED
@@ -0,0 +1,46 @@
|
|
1
|
+
LDSHARED_TEST = $(LDSHARED) $(LDFLAGS) test/test.o -o test/libtest.so $(LOCAL_LIBS)
|
2
|
+
|
3
|
+
libtest.so: test/libtest.so
|
4
|
+
|
5
|
+
test/libtest.so: test/test.o $(srcdir)/test/libtest.def
|
6
|
+
$(BUILD_RUBY) -rftools -e 'ARGV.each do|d|File.mkpath(File.dirname(d))end' $@
|
7
|
+
$(LDSHARED_TEST:dl.def=test/libtest.def)
|
8
|
+
|
9
|
+
test/test.o: $(srcdir)/test/test.c
|
10
|
+
@$(BUILD_RUBY) -rftools -e 'File.mkpath(*ARGV)' test
|
11
|
+
$(CC) $(CFLAGS) $(CPPFLAGS) -c $(srcdir)/test/test.c -o $@
|
12
|
+
|
13
|
+
test:: dl.so libtest.so force
|
14
|
+
$(BUILD_RUBY) -I. -I$(srcdir)/lib $(srcdir)/test/test.rb
|
15
|
+
|
16
|
+
force:
|
17
|
+
|
18
|
+
.PHONY: force test
|
19
|
+
|
20
|
+
allclean: distclean
|
21
|
+
@rm -f $(CLEANFILES) $(DISTCLEANFILES)
|
22
|
+
|
23
|
+
$(OBJS): ./dlconfig.h
|
24
|
+
|
25
|
+
sym.o: ruby.h dl.h call.func
|
26
|
+
|
27
|
+
dl.o: ruby.h dl.h callback.func cbtable.func
|
28
|
+
|
29
|
+
ptr.o: ruby.h dl.h
|
30
|
+
|
31
|
+
handle.o: ruby.h dl.h
|
32
|
+
|
33
|
+
call.func: $(srcdir)/mkcall.rb ./dlconfig.rb
|
34
|
+
@echo "Generating call.func"
|
35
|
+
@$(BUILD_RUBY) $(srcdir)/mkcall.rb $@
|
36
|
+
|
37
|
+
callback.func: $(srcdir)/mkcallback.rb ./dlconfig.rb
|
38
|
+
@echo "Generating callback.func"
|
39
|
+
@$(BUILD_RUBY) $(srcdir)/mkcallback.rb $@
|
40
|
+
|
41
|
+
cbtable.func: $(srcdir)/mkcbtable.rb ./dlconfig.rb
|
42
|
+
@echo "Generating cbtable.func"
|
43
|
+
@$(BUILD_RUBY) $(srcdir)/mkcbtable.rb $@
|
44
|
+
|
45
|
+
debug:
|
46
|
+
$(MAKE) CPPFLAGS="$(CPPFLAGS) -DDEBUG"
|
data/ext/rubysl/dl/dl.c
ADDED
@@ -0,0 +1,742 @@
|
|
1
|
+
/*
|
2
|
+
* $Id: dl.c 18479 2008-08-11 00:37:21Z shyouhei $
|
3
|
+
*/
|
4
|
+
|
5
|
+
#include "ruby.h"
|
6
|
+
|
7
|
+
#ifdef HAVE_RUBY_IO_H
|
8
|
+
#include "ruby/io.h"
|
9
|
+
#else
|
10
|
+
#include "rubyio.h"
|
11
|
+
#endif
|
12
|
+
|
13
|
+
#include <ctype.h>
|
14
|
+
#include "dl.h"
|
15
|
+
|
16
|
+
VALUE rb_mDL;
|
17
|
+
VALUE rb_eDLError;
|
18
|
+
VALUE rb_eDLTypeError;
|
19
|
+
|
20
|
+
static VALUE DLFuncTable;
|
21
|
+
static void *rb_dl_callback_table[CALLBACK_TYPES][MAX_CALLBACK];
|
22
|
+
static ID id_call;
|
23
|
+
|
24
|
+
static int
|
25
|
+
rb_dl_scan_callback_args(long stack[], const char *proto,
|
26
|
+
int *argc, VALUE argv[])
|
27
|
+
{
|
28
|
+
int i;
|
29
|
+
long *sp;
|
30
|
+
VALUE val;
|
31
|
+
|
32
|
+
sp = stack;
|
33
|
+
for (i=1; proto[i]; i++) {
|
34
|
+
switch (proto[i]) {
|
35
|
+
case 'C':
|
36
|
+
{
|
37
|
+
char v;
|
38
|
+
v = (char)(*sp);
|
39
|
+
sp++;
|
40
|
+
val = INT2NUM(v);
|
41
|
+
}
|
42
|
+
break;
|
43
|
+
case 'H':
|
44
|
+
{
|
45
|
+
short v;
|
46
|
+
v = (short)(*sp);
|
47
|
+
sp++;
|
48
|
+
val = INT2NUM(v);
|
49
|
+
}
|
50
|
+
break;
|
51
|
+
case 'I':
|
52
|
+
{
|
53
|
+
int v;
|
54
|
+
v = (int)(*sp);
|
55
|
+
sp++;
|
56
|
+
val = INT2NUM(v);
|
57
|
+
}
|
58
|
+
break;
|
59
|
+
case 'L':
|
60
|
+
{
|
61
|
+
long v;
|
62
|
+
v = (long)(*sp);
|
63
|
+
sp++;
|
64
|
+
val = INT2NUM(v);
|
65
|
+
}
|
66
|
+
break;
|
67
|
+
case 'F':
|
68
|
+
{
|
69
|
+
float v;
|
70
|
+
memcpy(&v, sp, sizeof(float));
|
71
|
+
sp += sizeof(float)/sizeof(long);
|
72
|
+
val = rb_float_new(v);
|
73
|
+
}
|
74
|
+
break;
|
75
|
+
case 'D':
|
76
|
+
{
|
77
|
+
double v;
|
78
|
+
memcpy(&v, sp, sizeof(double));
|
79
|
+
sp += sizeof(double)/sizeof(long);
|
80
|
+
val = rb_float_new(v);
|
81
|
+
}
|
82
|
+
break;
|
83
|
+
case 'P':
|
84
|
+
{
|
85
|
+
void *v;
|
86
|
+
memcpy(&v, sp, sizeof(void*));
|
87
|
+
sp++;
|
88
|
+
val = rb_dlptr_new(v, 0, 0);
|
89
|
+
}
|
90
|
+
break;
|
91
|
+
case 'S':
|
92
|
+
{
|
93
|
+
char *v;
|
94
|
+
memcpy(&v, sp, sizeof(void*));
|
95
|
+
sp++;
|
96
|
+
val = rb_tainted_str_new2(v);
|
97
|
+
}
|
98
|
+
break;
|
99
|
+
default:
|
100
|
+
rb_raise(rb_eDLTypeError, "unsupported type `%c'", proto[i]);
|
101
|
+
break;
|
102
|
+
}
|
103
|
+
argv[i-1] = val;
|
104
|
+
}
|
105
|
+
*argc = (i - 1);
|
106
|
+
|
107
|
+
return (*argc);
|
108
|
+
}
|
109
|
+
|
110
|
+
#include "callback.func"
|
111
|
+
|
112
|
+
static void
|
113
|
+
init_dl_func_table(){
|
114
|
+
#include "cbtable.func"
|
115
|
+
}
|
116
|
+
|
117
|
+
void *
|
118
|
+
dlmalloc(size_t size)
|
119
|
+
{
|
120
|
+
DEBUG_CODE2({
|
121
|
+
void *ptr;
|
122
|
+
|
123
|
+
printf("dlmalloc(%d)",size);
|
124
|
+
ptr = xmalloc(size);
|
125
|
+
printf(":0x%x\n",ptr);
|
126
|
+
return ptr;
|
127
|
+
},
|
128
|
+
{
|
129
|
+
return xmalloc(size);
|
130
|
+
});
|
131
|
+
}
|
132
|
+
|
133
|
+
void *
|
134
|
+
dlrealloc(void *ptr, size_t size)
|
135
|
+
{
|
136
|
+
DEBUG_CODE({
|
137
|
+
printf("dlrealloc(0x%x,%d)\n",ptr,size);
|
138
|
+
});
|
139
|
+
return xrealloc(ptr, size);
|
140
|
+
}
|
141
|
+
|
142
|
+
void
|
143
|
+
dlfree(void *ptr)
|
144
|
+
{
|
145
|
+
DEBUG_CODE({
|
146
|
+
printf("dlfree(0x%x)\n",ptr);
|
147
|
+
});
|
148
|
+
xfree(ptr);
|
149
|
+
}
|
150
|
+
|
151
|
+
char*
|
152
|
+
dlstrdup(const char *str)
|
153
|
+
{
|
154
|
+
char *newstr;
|
155
|
+
|
156
|
+
newstr = (char*)dlmalloc(strlen(str)+1);
|
157
|
+
strcpy(newstr,str);
|
158
|
+
|
159
|
+
return newstr;
|
160
|
+
}
|
161
|
+
|
162
|
+
size_t
|
163
|
+
dlsizeof(const char *cstr)
|
164
|
+
{
|
165
|
+
size_t size;
|
166
|
+
int i, len, n, dlen;
|
167
|
+
char *d;
|
168
|
+
|
169
|
+
len = strlen(cstr);
|
170
|
+
size = 0;
|
171
|
+
for (i=0; i<len; i++) {
|
172
|
+
n = 1;
|
173
|
+
if (isdigit(cstr[i+1])) {
|
174
|
+
dlen = 1;
|
175
|
+
while (isdigit(cstr[i+dlen])) { dlen ++; };
|
176
|
+
dlen --;
|
177
|
+
d = ALLOCA_N(char, dlen + 1);
|
178
|
+
strncpy(d, cstr + i + 1, dlen);
|
179
|
+
d[dlen] = '\0';
|
180
|
+
n = atoi(d);
|
181
|
+
}
|
182
|
+
else{
|
183
|
+
dlen = 0;
|
184
|
+
}
|
185
|
+
|
186
|
+
switch (cstr[i]) {
|
187
|
+
case 'I':
|
188
|
+
DLALIGN(0,size,INT_ALIGN);
|
189
|
+
case 'i':
|
190
|
+
size += sizeof(int) * n;
|
191
|
+
break;
|
192
|
+
case 'L':
|
193
|
+
DLALIGN(0,size,LONG_ALIGN);
|
194
|
+
case 'l':
|
195
|
+
size += sizeof(long) * n;
|
196
|
+
break;
|
197
|
+
case 'F':
|
198
|
+
DLALIGN(0,size,FLOAT_ALIGN);
|
199
|
+
case 'f':
|
200
|
+
size += sizeof(float) * n;
|
201
|
+
break;
|
202
|
+
case 'D':
|
203
|
+
DLALIGN(0,size,DOUBLE_ALIGN);
|
204
|
+
case 'd':
|
205
|
+
size += sizeof(double) * n;
|
206
|
+
break;
|
207
|
+
case 'C':
|
208
|
+
case 'c':
|
209
|
+
size += sizeof(char) * n;
|
210
|
+
break;
|
211
|
+
case 'H':
|
212
|
+
DLALIGN(0,size,SHORT_ALIGN);
|
213
|
+
case 'h':
|
214
|
+
size += sizeof(short) * n;
|
215
|
+
break;
|
216
|
+
case 'P':
|
217
|
+
case 'S':
|
218
|
+
DLALIGN(0,size,VOIDP_ALIGN);
|
219
|
+
case 'p':
|
220
|
+
case 's':
|
221
|
+
size += sizeof(void*) * n;
|
222
|
+
break;
|
223
|
+
default:
|
224
|
+
rb_raise(rb_eDLTypeError, "unexpected type '%c'", cstr[i]);
|
225
|
+
break;
|
226
|
+
}
|
227
|
+
i += dlen;
|
228
|
+
}
|
229
|
+
|
230
|
+
return size;
|
231
|
+
}
|
232
|
+
|
233
|
+
static float *
|
234
|
+
c_farray(VALUE v, long *size)
|
235
|
+
{
|
236
|
+
int i, len;
|
237
|
+
float *ary;
|
238
|
+
VALUE e;
|
239
|
+
|
240
|
+
len = RARRAY_LEN(v);
|
241
|
+
*size = sizeof(float) * len;
|
242
|
+
ary = dlmalloc(*size);
|
243
|
+
for (i=0; i < len; i++) {
|
244
|
+
e = rb_ary_entry(v, i);
|
245
|
+
switch (TYPE(e)) {
|
246
|
+
case T_FLOAT:
|
247
|
+
ary[i] = (float)(RFLOAT(e)->value);
|
248
|
+
break;
|
249
|
+
case T_NIL:
|
250
|
+
ary[i] = 0.0;
|
251
|
+
break;
|
252
|
+
default:
|
253
|
+
rb_raise(rb_eDLTypeError, "unexpected type of the element #%d", i);
|
254
|
+
break;
|
255
|
+
}
|
256
|
+
}
|
257
|
+
|
258
|
+
return ary;
|
259
|
+
}
|
260
|
+
|
261
|
+
static double *
|
262
|
+
c_darray(VALUE v, long *size)
|
263
|
+
{
|
264
|
+
int i, len;
|
265
|
+
double *ary;
|
266
|
+
VALUE e;
|
267
|
+
|
268
|
+
len = RARRAY_LEN(v);
|
269
|
+
*size = sizeof(double) * len;
|
270
|
+
ary = dlmalloc(*size);
|
271
|
+
for (i=0; i < len; i++) {
|
272
|
+
e = rb_ary_entry(v, i);
|
273
|
+
switch (TYPE(e)) {
|
274
|
+
case T_FLOAT:
|
275
|
+
ary[i] = (double)(RFLOAT(e)->value);
|
276
|
+
break;
|
277
|
+
case T_NIL:
|
278
|
+
ary[i] = 0.0;
|
279
|
+
break;
|
280
|
+
default:
|
281
|
+
rb_raise(rb_eDLTypeError, "unexpected type of the element #%d", i);
|
282
|
+
break;
|
283
|
+
}
|
284
|
+
}
|
285
|
+
|
286
|
+
return ary;
|
287
|
+
}
|
288
|
+
|
289
|
+
static long *
|
290
|
+
c_larray(VALUE v, long *size)
|
291
|
+
{
|
292
|
+
int i, len;
|
293
|
+
long *ary;
|
294
|
+
VALUE e;
|
295
|
+
|
296
|
+
len = RARRAY_LEN(v);
|
297
|
+
*size = sizeof(long) * len;
|
298
|
+
ary = dlmalloc(*size);
|
299
|
+
for (i=0; i < len; i++) {
|
300
|
+
e = rb_ary_entry(v, i);
|
301
|
+
switch (TYPE(e)) {
|
302
|
+
case T_FIXNUM:
|
303
|
+
case T_BIGNUM:
|
304
|
+
ary[i] = (long)(NUM2INT(e));
|
305
|
+
break;
|
306
|
+
case T_NIL:
|
307
|
+
ary[i] = 0;
|
308
|
+
break;
|
309
|
+
default:
|
310
|
+
rb_raise(rb_eDLTypeError, "unexpected type of the element #%d", i);
|
311
|
+
break;
|
312
|
+
}
|
313
|
+
}
|
314
|
+
|
315
|
+
return ary;
|
316
|
+
}
|
317
|
+
|
318
|
+
static int *
|
319
|
+
c_iarray(VALUE v, long *size)
|
320
|
+
{
|
321
|
+
int i, len;
|
322
|
+
int *ary;
|
323
|
+
VALUE e;
|
324
|
+
|
325
|
+
len = RARRAY_LEN(v);
|
326
|
+
*size = sizeof(int) * len;
|
327
|
+
ary = dlmalloc(*size);
|
328
|
+
for (i=0; i < len; i++) {
|
329
|
+
e = rb_ary_entry(v, i);
|
330
|
+
switch (TYPE(e)) {
|
331
|
+
case T_FIXNUM:
|
332
|
+
case T_BIGNUM:
|
333
|
+
ary[i] = (int)(NUM2INT(e));
|
334
|
+
break;
|
335
|
+
case T_NIL:
|
336
|
+
ary[i] = 0;
|
337
|
+
break;
|
338
|
+
default:
|
339
|
+
rb_raise(rb_eDLTypeError, "unexpected type of the element #%d", i);
|
340
|
+
break;
|
341
|
+
}
|
342
|
+
}
|
343
|
+
|
344
|
+
return ary;
|
345
|
+
}
|
346
|
+
|
347
|
+
static short *
|
348
|
+
c_harray(VALUE v, long *size)
|
349
|
+
{
|
350
|
+
int i, len;
|
351
|
+
short *ary;
|
352
|
+
VALUE e;
|
353
|
+
|
354
|
+
len = RARRAY_LEN(v);
|
355
|
+
*size = sizeof(short) * len;
|
356
|
+
ary = dlmalloc(*size);
|
357
|
+
for (i=0; i < len; i++) {
|
358
|
+
e = rb_ary_entry(v, i);
|
359
|
+
switch (TYPE(e)) {
|
360
|
+
case T_FIXNUM:
|
361
|
+
case T_BIGNUM:
|
362
|
+
ary[i] = (short)(NUM2INT(e));
|
363
|
+
break;
|
364
|
+
case T_NIL:
|
365
|
+
ary[i] = 0;
|
366
|
+
break;
|
367
|
+
default:
|
368
|
+
rb_raise(rb_eDLTypeError, "unexpected type of the element #%d", i);
|
369
|
+
break;
|
370
|
+
}
|
371
|
+
}
|
372
|
+
|
373
|
+
return ary;
|
374
|
+
}
|
375
|
+
|
376
|
+
static char *
|
377
|
+
c_carray(VALUE v, long *size)
|
378
|
+
{
|
379
|
+
int i, len;
|
380
|
+
char *ary;
|
381
|
+
VALUE e;
|
382
|
+
|
383
|
+
len = RARRAY_LEN(v);
|
384
|
+
*size = sizeof(char) * len;
|
385
|
+
ary = dlmalloc(*size);
|
386
|
+
for (i=0; i < len; i++) {
|
387
|
+
e = rb_ary_entry(v, i);
|
388
|
+
switch (TYPE(e)) {
|
389
|
+
case T_FIXNUM:
|
390
|
+
case T_BIGNUM:
|
391
|
+
ary[i] = (char)(NUM2INT(e));
|
392
|
+
break;
|
393
|
+
case T_NIL:
|
394
|
+
ary[i] = 0;
|
395
|
+
break;
|
396
|
+
default:
|
397
|
+
rb_raise(rb_eDLTypeError, "unexpected type of the element #%d", i);
|
398
|
+
break;
|
399
|
+
}
|
400
|
+
}
|
401
|
+
|
402
|
+
return ary;
|
403
|
+
}
|
404
|
+
|
405
|
+
static void *
|
406
|
+
c_parray(VALUE v, long *size)
|
407
|
+
{
|
408
|
+
int i, len;
|
409
|
+
void **ary;
|
410
|
+
VALUE e, tmp;
|
411
|
+
|
412
|
+
len = RARRAY_LEN(v);
|
413
|
+
*size = sizeof(void*) * len;
|
414
|
+
ary = dlmalloc(*size);
|
415
|
+
for (i=0; i < len; i++) {
|
416
|
+
e = rb_ary_entry(v, i);
|
417
|
+
switch (TYPE(e)) {
|
418
|
+
default:
|
419
|
+
tmp = rb_check_string_type(e);
|
420
|
+
if (NIL_P(tmp)) {
|
421
|
+
rb_raise(rb_eDLTypeError, "unexpected type of the element #%d", i);
|
422
|
+
}
|
423
|
+
e = tmp;
|
424
|
+
/* fall through */
|
425
|
+
case T_STRING:
|
426
|
+
rb_check_safe_str(e);
|
427
|
+
{
|
428
|
+
char *str, *src;
|
429
|
+
src = RSTRING(e)->ptr;
|
430
|
+
str = dlstrdup(src);
|
431
|
+
ary[i] = (void*)str;
|
432
|
+
}
|
433
|
+
break;
|
434
|
+
case T_NIL:
|
435
|
+
ary[i] = NULL;
|
436
|
+
break;
|
437
|
+
case T_DATA:
|
438
|
+
if (rb_obj_is_kind_of(e, rb_cDLPtrData)) {
|
439
|
+
struct ptr_data *pdata;
|
440
|
+
Data_Get_Struct(e, struct ptr_data, pdata);
|
441
|
+
ary[i] = (void*)(pdata->ptr);
|
442
|
+
}
|
443
|
+
else{
|
444
|
+
e = rb_funcall(e, rb_intern("to_ptr"), 0);
|
445
|
+
if (rb_obj_is_kind_of(e, rb_cDLPtrData)) {
|
446
|
+
struct ptr_data *pdata;
|
447
|
+
Data_Get_Struct(e, struct ptr_data, pdata);
|
448
|
+
ary[i] = (void*)(pdata->ptr);
|
449
|
+
}
|
450
|
+
else{
|
451
|
+
rb_raise(rb_eDLTypeError, "unexpected type of the element #%d", i);
|
452
|
+
}
|
453
|
+
}
|
454
|
+
break;
|
455
|
+
}
|
456
|
+
}
|
457
|
+
|
458
|
+
return ary;
|
459
|
+
}
|
460
|
+
|
461
|
+
void *
|
462
|
+
rb_ary2cary(char t, VALUE v, long *size)
|
463
|
+
{
|
464
|
+
int len;
|
465
|
+
VALUE val0;
|
466
|
+
|
467
|
+
val0 = rb_check_array_type(v);
|
468
|
+
if(NIL_P(val0)) {
|
469
|
+
rb_raise(rb_eDLTypeError, "an array is expected.");
|
470
|
+
}
|
471
|
+
v = val0;
|
472
|
+
|
473
|
+
len = RARRAY_LEN(v);
|
474
|
+
if (len == 0) {
|
475
|
+
return NULL;
|
476
|
+
}
|
477
|
+
|
478
|
+
if (!size) {
|
479
|
+
size = ALLOCA_N(long,1);
|
480
|
+
}
|
481
|
+
|
482
|
+
val0 = rb_ary_entry(v,0);
|
483
|
+
switch (TYPE(val0)) {
|
484
|
+
case T_FIXNUM:
|
485
|
+
case T_BIGNUM:
|
486
|
+
switch (t) {
|
487
|
+
case 'C': case 'c':
|
488
|
+
return (void*)c_carray(v,size);
|
489
|
+
case 'H': case 'h':
|
490
|
+
return (void*)c_harray(v,size);
|
491
|
+
case 'I': case 'i':
|
492
|
+
return (void*)c_iarray(v,size);
|
493
|
+
case 'L': case 'l': case 0:
|
494
|
+
return (void*)c_larray(v,size);
|
495
|
+
default:
|
496
|
+
rb_raise(rb_eDLTypeError, "type mismatch");
|
497
|
+
}
|
498
|
+
case T_STRING:
|
499
|
+
return (void*)c_parray(v,size);
|
500
|
+
case T_FLOAT:
|
501
|
+
switch (t) {
|
502
|
+
case 'F': case 'f':
|
503
|
+
return (void*)c_farray(v,size);
|
504
|
+
case 'D': case 'd': case 0:
|
505
|
+
return (void*)c_darray(v,size);
|
506
|
+
}
|
507
|
+
rb_raise(rb_eDLTypeError, "type mismatch");
|
508
|
+
case T_DATA:
|
509
|
+
if (rb_obj_is_kind_of(val0, rb_cDLPtrData)) {
|
510
|
+
return (void*)c_parray(v,size);
|
511
|
+
}
|
512
|
+
else{
|
513
|
+
val0 = rb_funcall(val0, rb_intern("to_ptr"), 0);
|
514
|
+
if (rb_obj_is_kind_of(val0, rb_cDLPtrData)) {
|
515
|
+
return (void*)c_parray(v,size);
|
516
|
+
}
|
517
|
+
}
|
518
|
+
rb_raise(rb_eDLTypeError, "type mismatch");
|
519
|
+
case T_NIL:
|
520
|
+
return (void*)c_parray(v, size);
|
521
|
+
default:
|
522
|
+
rb_raise(rb_eDLTypeError, "unsupported type");
|
523
|
+
}
|
524
|
+
}
|
525
|
+
|
526
|
+
VALUE
|
527
|
+
rb_str_to_ptr(VALUE self)
|
528
|
+
{
|
529
|
+
char *ptr;
|
530
|
+
int len;
|
531
|
+
VALUE p;
|
532
|
+
|
533
|
+
len = RSTRING(self)->len;
|
534
|
+
ptr = (char*)dlmalloc(len + 1);
|
535
|
+
memcpy(ptr, RSTRING(self)->ptr, len);
|
536
|
+
ptr[len] = '\0';
|
537
|
+
p = rb_dlptr_new((void*)ptr,len,dlfree);
|
538
|
+
OBJ_INFECT(p, self);
|
539
|
+
return p;
|
540
|
+
}
|
541
|
+
|
542
|
+
VALUE
|
543
|
+
rb_ary_to_ptr(int argc, VALUE argv[], VALUE self)
|
544
|
+
{
|
545
|
+
void *ptr = 0;
|
546
|
+
VALUE t;
|
547
|
+
long size;
|
548
|
+
|
549
|
+
switch (rb_scan_args(argc, argv, "01", &t)) {
|
550
|
+
case 1:
|
551
|
+
ptr = rb_ary2cary(StringValuePtr(t)[0], self, &size);
|
552
|
+
break;
|
553
|
+
case 0:
|
554
|
+
ptr = rb_ary2cary(0, self, &size);
|
555
|
+
break;
|
556
|
+
}
|
557
|
+
if (ptr) {
|
558
|
+
VALUE p = rb_dlptr_new(ptr, size, dlfree);
|
559
|
+
OBJ_INFECT(p, self);
|
560
|
+
return p;
|
561
|
+
}
|
562
|
+
return Qnil;
|
563
|
+
}
|
564
|
+
|
565
|
+
VALUE
|
566
|
+
rb_io_to_ptr(VALUE self)
|
567
|
+
{
|
568
|
+
rb_io_t *fptr;
|
569
|
+
FILE *fp;
|
570
|
+
|
571
|
+
GetOpenFile(self, fptr);
|
572
|
+
fp = fptr->f;
|
573
|
+
|
574
|
+
return fp ? rb_dlptr_new(fp, 0, 0) : Qnil;
|
575
|
+
}
|
576
|
+
|
577
|
+
VALUE
|
578
|
+
rb_dl_dlopen(int argc, VALUE argv[], VALUE self)
|
579
|
+
{
|
580
|
+
rb_secure(2);
|
581
|
+
return rb_class_new_instance(argc, argv, rb_cDLHandle);
|
582
|
+
}
|
583
|
+
|
584
|
+
VALUE
|
585
|
+
rb_dl_malloc(VALUE self, VALUE size)
|
586
|
+
{
|
587
|
+
rb_secure(4);
|
588
|
+
return rb_dlptr_malloc(DLNUM2LONG(size), dlfree);
|
589
|
+
}
|
590
|
+
|
591
|
+
VALUE
|
592
|
+
rb_dl_strdup(VALUE self, VALUE str)
|
593
|
+
{
|
594
|
+
SafeStringValue(str);
|
595
|
+
return rb_dlptr_new(strdup(RSTRING(str)->ptr), RSTRING(str)->len, dlfree);
|
596
|
+
}
|
597
|
+
|
598
|
+
static VALUE
|
599
|
+
rb_dl_sizeof(VALUE self, VALUE str)
|
600
|
+
{
|
601
|
+
return INT2NUM(dlsizeof(StringValuePtr(str)));
|
602
|
+
}
|
603
|
+
|
604
|
+
static VALUE
|
605
|
+
rb_dl_callback(int argc, VALUE argv[], VALUE self)
|
606
|
+
{
|
607
|
+
VALUE type, proc;
|
608
|
+
int rettype, entry, i;
|
609
|
+
char fname[127];
|
610
|
+
|
611
|
+
rb_secure(4);
|
612
|
+
proc = Qnil;
|
613
|
+
switch (rb_scan_args(argc, argv, "11", &type, &proc)) {
|
614
|
+
case 1:
|
615
|
+
if (rb_block_given_p()) {
|
616
|
+
proc = rb_block_proc();
|
617
|
+
}
|
618
|
+
else{
|
619
|
+
proc = Qnil;
|
620
|
+
}
|
621
|
+
default:
|
622
|
+
break;
|
623
|
+
}
|
624
|
+
|
625
|
+
StringValue(type);
|
626
|
+
switch (RSTRING(type)->ptr[0]) {
|
627
|
+
case '0':
|
628
|
+
rettype = 0x00;
|
629
|
+
break;
|
630
|
+
case 'C':
|
631
|
+
rettype = 0x01;
|
632
|
+
break;
|
633
|
+
case 'H':
|
634
|
+
rettype = 0x02;
|
635
|
+
break;
|
636
|
+
case 'I':
|
637
|
+
rettype = 0x03;
|
638
|
+
break;
|
639
|
+
case 'L':
|
640
|
+
rettype = 0x04;
|
641
|
+
break;
|
642
|
+
case 'F':
|
643
|
+
rettype = 0x05;
|
644
|
+
break;
|
645
|
+
case 'D':
|
646
|
+
rettype = 0x06;
|
647
|
+
break;
|
648
|
+
case 'P':
|
649
|
+
rettype = 0x07;
|
650
|
+
break;
|
651
|
+
default:
|
652
|
+
rb_raise(rb_eDLTypeError, "unsupported type `%c'", RSTRING(type)->ptr[0]);
|
653
|
+
}
|
654
|
+
|
655
|
+
entry = -1;
|
656
|
+
for (i=0; i < MAX_CALLBACK; i++) {
|
657
|
+
if (rb_hash_aref(DLFuncTable, rb_assoc_new(INT2NUM(rettype), INT2NUM(i))) == Qnil) {
|
658
|
+
entry = i;
|
659
|
+
break;
|
660
|
+
}
|
661
|
+
}
|
662
|
+
if (entry < 0) {
|
663
|
+
rb_raise(rb_eDLError, "too many callbacks are defined.");
|
664
|
+
}
|
665
|
+
|
666
|
+
rb_hash_aset(DLFuncTable,
|
667
|
+
rb_assoc_new(INT2NUM(rettype),INT2NUM(entry)),
|
668
|
+
rb_assoc_new(type,proc));
|
669
|
+
sprintf(fname, "rb_dl_callback_func_%d_%d", rettype, entry);
|
670
|
+
return rb_dlsym_new((void (*)())rb_dl_callback_table[rettype][entry],
|
671
|
+
fname, RSTRING(type)->ptr);
|
672
|
+
}
|
673
|
+
|
674
|
+
static VALUE
|
675
|
+
rb_dl_remove_callback(VALUE mod, VALUE sym)
|
676
|
+
{
|
677
|
+
freefunc_t f;
|
678
|
+
int i, j;
|
679
|
+
|
680
|
+
rb_secure(4);
|
681
|
+
f = rb_dlsym2csym(sym);
|
682
|
+
for (i=0; i < CALLBACK_TYPES; i++) {
|
683
|
+
for (j=0; j < MAX_CALLBACK; j++) {
|
684
|
+
if (rb_dl_callback_table[i][j] == f) {
|
685
|
+
rb_hash_aset(DLFuncTable, rb_assoc_new(INT2NUM(i),INT2NUM(j)),Qnil);
|
686
|
+
break;
|
687
|
+
}
|
688
|
+
}
|
689
|
+
}
|
690
|
+
return Qnil;
|
691
|
+
}
|
692
|
+
|
693
|
+
void
|
694
|
+
Init_dl()
|
695
|
+
{
|
696
|
+
void Init_dlptr();
|
697
|
+
void Init_dlsym();
|
698
|
+
void Init_dlhandle();
|
699
|
+
|
700
|
+
id_call = rb_intern("call");
|
701
|
+
|
702
|
+
rb_mDL = rb_define_module("DL");
|
703
|
+
|
704
|
+
rb_eDLError = rb_define_class_under(rb_mDL, "DLError", rb_eStandardError);
|
705
|
+
rb_eDLTypeError = rb_define_class_under(rb_mDL, "DLTypeError", rb_eDLError);
|
706
|
+
|
707
|
+
DLFuncTable = rb_hash_new();
|
708
|
+
init_dl_func_table();
|
709
|
+
rb_define_const(rb_mDL, "FuncTable", DLFuncTable);
|
710
|
+
|
711
|
+
rb_define_const(rb_mDL, "RTLD_GLOBAL", INT2NUM(RTLD_GLOBAL));
|
712
|
+
rb_define_const(rb_mDL, "RTLD_LAZY", INT2NUM(RTLD_LAZY));
|
713
|
+
rb_define_const(rb_mDL, "RTLD_NOW", INT2NUM(RTLD_NOW));
|
714
|
+
|
715
|
+
rb_define_const(rb_mDL, "ALIGN_INT", INT2NUM(ALIGN_INT));
|
716
|
+
rb_define_const(rb_mDL, "ALIGN_LONG", INT2NUM(ALIGN_LONG));
|
717
|
+
rb_define_const(rb_mDL, "ALIGN_FLOAT", INT2NUM(ALIGN_FLOAT));
|
718
|
+
rb_define_const(rb_mDL, "ALIGN_SHORT", INT2NUM(ALIGN_SHORT));
|
719
|
+
rb_define_const(rb_mDL, "ALIGN_DOUBLE",INT2NUM(ALIGN_DOUBLE));
|
720
|
+
rb_define_const(rb_mDL, "ALIGN_VOIDP", INT2NUM(ALIGN_VOIDP));
|
721
|
+
|
722
|
+
rb_define_const(rb_mDL, "MAX_ARG", INT2NUM(MAX_ARG));
|
723
|
+
rb_define_const(rb_mDL, "DLSTACK", rb_tainted_str_new2(DLSTACK_METHOD));
|
724
|
+
|
725
|
+
rb_define_module_function(rb_mDL, "dlopen", rb_dl_dlopen, -1);
|
726
|
+
rb_define_module_function(rb_mDL, "callback", rb_dl_callback, -1);
|
727
|
+
rb_define_module_function(rb_mDL, "define_callback", rb_dl_callback, -1);
|
728
|
+
rb_define_module_function(rb_mDL, "remove_callback", rb_dl_remove_callback, 1);
|
729
|
+
rb_define_module_function(rb_mDL, "malloc", rb_dl_malloc, 1);
|
730
|
+
rb_define_module_function(rb_mDL, "strdup", rb_dl_strdup, 1);
|
731
|
+
rb_define_module_function(rb_mDL, "sizeof", rb_dl_sizeof, 1);
|
732
|
+
|
733
|
+
Init_dlptr();
|
734
|
+
Init_dlsym();
|
735
|
+
Init_dlhandle();
|
736
|
+
|
737
|
+
rb_define_const(rb_mDL, "FREE", rb_dlsym_new(dlfree, "free", "0P"));
|
738
|
+
|
739
|
+
rb_define_method(rb_cString, "to_ptr", rb_str_to_ptr, 0);
|
740
|
+
rb_define_method(rb_cArray, "to_ptr", rb_ary_to_ptr, -1);
|
741
|
+
rb_define_method(rb_cIO, "to_ptr", rb_io_to_ptr, 0);
|
742
|
+
}
|