rubysl-dl 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -15,4 +15,3 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
- .rbx
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ before_install:
3
+ - gem update --system
4
+ - gem --version
5
+ - gem install rubysl-bundler
6
+ script: bundle exec mspec spec
7
+ rvm:
8
+ - rbx-nightly-18mode
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # RubySL::Dl
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 'Added some feature'`)
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
@@ -1,2 +1 @@
1
- #!/usr/bin/env rake
2
1
  require "bundler/gem_tasks"
@@ -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"
@@ -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
+ }