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.
@@ -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
+ }