DEFINITIONS
This source file includes following functions.
- char2type
- dlsym_free
- rb_dlsym_new
- rb_dlsym2csym
- rb_dlsym_s_allocate
- rb_dlsym_initialize
- rb_s_dlsym_char2type
- rb_dlsym_name
- rb_dlsym_proto
- rb_dlsym_cproto
- rb_dlsym_inspect
- stack_size
- rb_dlsym_call
- rb_dlsym_to_i
- rb_dlsym_to_ptr
- Init_dlsym
1
2
3
4
5 #include <ruby.h>
6 #include "dl.h"
7
8 VALUE rb_cDLSymbol;
9
10 static const char *
11 char2type(int ch)
12 {
13 switch (ch) {
14 case '0':
15 return "void";
16 case 'P':
17 return "void *";
18 case 'p':
19 return "void *";
20 case 'C':
21 return "char";
22 case 'c':
23 return "char *";
24 case 'H':
25 return "short";
26 case 'h':
27 return "short *";
28 case 'I':
29 return "int";
30 case 'i':
31 return "int *";
32 case 'L':
33 return "long";
34 case 'l':
35 return "long *";
36 case 'F':
37 return "double";
38 case 'f':
39 return "double *";
40 case 'D':
41 return "double";
42 case 'd':
43 return "double *";
44 case 'S':
45 return "const char *";
46 case 's':
47 return "char *";
48 case 'A':
49 return "[]";
50 case 'a':
51 return "[]";
52 };
53 return NULL;
54 }
55
56 void
57 dlsym_free(struct sym_data *data)
58 {
59 if( data->name ){
60 DEBUG_CODE({
61 printf("dlsym_free(): free(data->name:%s)\n",data->name);
62 });
63 free(data->name);
64 };
65 if( data->type ){
66 DEBUG_CODE({
67 printf("dlsym_free(): free(data->type:%s)\n",data->type);
68 });
69 free(data->type);
70 };
71 }
72
73 VALUE
74 rb_dlsym_new(void (*func)(), const char *name, const char *type)
75 {
76 VALUE val;
77 struct sym_data *data;
78 const char *ptype;
79
80 if( !type || !type[0] ){
81 return rb_dlptr_new((void*)func, 0, 0);
82 };
83
84 for( ptype = type; *ptype; ptype ++ ){
85 if( ! char2type(*ptype) ){
86 rb_raise(rb_eDLTypeError, "unknown type specifier '%c'", *ptype);
87 };
88 };
89
90 if( func ){
91 val = Data_Make_Struct(rb_cDLSymbol, struct sym_data, 0, dlsym_free, data);
92 data->func = func;
93 data->name = name ? strdup(name) : NULL;
94 data->type = type ? strdup(type) : NULL;
95 data->len = type ? strlen(type) : 0;
96 #if !(defined(DLSTACK))
97 if( data->len - 1 > MAX_ARG ){
98 rb_raise(rb_eDLError, "maximum number of arguments is %d.", MAX_ARG);
99 };
100 #endif
101 }
102 else{
103 val = Qnil;
104 };
105
106 return val;
107 }
108
109 freefunc_t
110 rb_dlsym2csym(VALUE val)
111 {
112 struct sym_data *data;
113 freefunc_t func;
114
115 if( rb_obj_is_kind_of(val, rb_cDLSymbol) ){
116 Data_Get_Struct(val, struct sym_data, data);
117 func = data->func;
118 }
119 else if( val == Qnil ){
120 func = NULL;
121 }
122 else{
123 rb_raise(rb_eTypeError, "DL::Symbol was expected");
124 };
125
126 return func;
127 }
128
129 VALUE
130 rb_dlsym_s_allocate(VALUE klass)
131 {
132 VALUE obj;
133 struct sym_data *data;
134
135 obj = Data_Make_Struct(klass, struct sym_data, 0, dlsym_free, data);
136 data->func = 0;
137 data->name = 0;
138 data->type = 0;
139 data->len = 0;
140
141 return obj;
142 }
143
144 VALUE
145 rb_dlsym_initialize(int argc, VALUE argv[], VALUE self)
146 {
147 VALUE addr, name, type;
148 VALUE val;
149 struct sym_data *data;
150 void *saddr;
151 const char *sname, *stype;
152
153 rb_scan_args(argc, argv, "12", &addr, &name, &type);
154
155 saddr = (void*)(DLNUM2LONG(rb_Integer(addr)));
156 sname = NIL_P(name) ? NULL : StringValuePtr(name);
157 stype = NIL_P(type) ? NULL : StringValuePtr(type);
158
159 if( saddr ){
160 Data_Get_Struct(self, struct sym_data, data);
161 if( data->name ) free(data->name);
162 if( data->type ) free(data->type);
163 data->func = saddr;
164 data->name = sname ? strdup(sname) : 0;
165 data->type = stype ? strdup(stype) : 0;
166 data->len = stype ? strlen(stype) : 0;
167 }
168
169 return Qnil;
170 }
171
172 VALUE
173 rb_s_dlsym_char2type(VALUE self, VALUE ch)
174 {
175 const char *type;
176
177 type = char2type(StringValuePtr(ch)[0]);
178
179 if (type == NULL)
180 return Qnil;
181 else
182 return rb_str_new2(type);
183 }
184
185 VALUE
186 rb_dlsym_name(VALUE self)
187 {
188 struct sym_data *sym;
189
190 Data_Get_Struct(self, struct sym_data, sym);
191 return sym->name ? rb_tainted_str_new2(sym->name) : Qnil;
192 }
193
194 VALUE
195 rb_dlsym_proto(VALUE self)
196 {
197 struct sym_data *sym;
198
199 Data_Get_Struct(self, struct sym_data, sym);
200 return sym->type ? rb_tainted_str_new2(sym->type) : Qnil;
201 }
202
203 VALUE
204 rb_dlsym_cproto(VALUE self)
205 {
206 struct sym_data *sym;
207 const char *ptype, *typestr;
208 size_t len;
209 VALUE val;
210
211 Data_Get_Struct(self, struct sym_data, sym);
212
213 ptype = sym->type;
214
215 if( ptype ){
216 typestr = char2type(*ptype++);
217 len = strlen(typestr);
218
219 val = rb_tainted_str_new(typestr, len);
220 if (typestr[len - 1] != '*')
221 rb_str_cat(val, " ", 1);
222
223 if( sym->name ){
224 rb_str_cat2(val, sym->name);
225 }
226 else{
227 rb_str_cat2(val, "(null)");
228 };
229 rb_str_cat(val, "(", 1);
230
231 while (*ptype) {
232 const char *ty = char2type(*ptype++);
233 rb_str_cat2(val, ty);
234 if (*ptype)
235 rb_str_cat(val, ", ", 2);
236 }
237
238 rb_str_cat(val, ");", 2);
239 }
240 else{
241 val = rb_tainted_str_new2("void (");
242 if( sym->name ){
243 rb_str_cat2(val, sym->name);
244 }
245 else{
246 rb_str_cat2(val, "(null)");
247 };
248 rb_str_cat2(val, ")()");
249 };
250
251 return val;
252 }
253
254 VALUE
255 rb_dlsym_inspect(VALUE self)
256 {
257 VALUE proto;
258 VALUE val;
259 char *str;
260 int str_size;
261 struct sym_data *sym;
262
263 Data_Get_Struct(self, struct sym_data, sym);
264 proto = rb_dlsym_cproto(self);
265
266 str_size = RSTRING(proto)->len + 100;
267 str = dlmalloc(str_size);
268 snprintf(str, str_size - 1,
269 "#<DL::Symbol:0x%x func=0x%x '%s'>",
270 sym, sym->func, RSTRING(proto)->ptr);
271 val = rb_tainted_str_new2(str);
272 dlfree(str);
273
274 return val;
275 }
276
277 static int
278 stack_size(struct sym_data *sym)
279 {
280 int i;
281 int size;
282
283 size = 0;
284 for( i=1; i < sym->len; i++ ){
285 switch(sym->type[i]){
286 case 'C':
287 case 'H':
288 case 'I':
289 case 'L':
290 size += sizeof(long);
291 break;
292 case 'F':
293 size += sizeof(float);
294 break;
295 case 'D':
296 size += sizeof(double);
297 break;
298 case 'c':
299 case 'h':
300 case 'i':
301 case 'l':
302 case 'f':
303 case 'd':
304 case 'p':
305 case 'P':
306 case 's':
307 case 'S':
308 case 'a':
309 case 'A':
310 size += sizeof(void*);
311 break;
312 default:
313 return -(sym->type[i]);
314 }
315 }
316 return size;
317 }
318
319 VALUE
320 rb_dlsym_call(int argc, VALUE argv[], VALUE self)
321 {
322 struct sym_data *sym;
323 ANY_TYPE *args;
324 ANY_TYPE *dargs;
325 ANY_TYPE ret;
326 int *dtypes;
327 VALUE val;
328 VALUE dvals;
329 int i;
330 long ftype;
331 void *func;
332
333 Data_Get_Struct(self, struct sym_data, sym);
334 DEBUG_CODE({
335 printf("rb_dlsym_call(): type = '%s', func = 0x%x\n", sym->type, sym->func);
336 });
337 if( (sym->len - 1) != argc ){
338 rb_raise(rb_eArgError, "%d arguments are needed", sym->len - 1);
339 };
340
341 ftype = 0;
342 dvals = Qnil;
343
344 args = ALLOC_N(ANY_TYPE, sym->len - 1);
345 dargs = ALLOC_N(ANY_TYPE, sym->len - 1);
346 dtypes = ALLOC_N(int, sym->len - 1);
347 #define FREE_ARGS {xfree(args); xfree(dargs); xfree(dtypes);}
348
349 for( i = sym->len - 2; i >= 0; i-- ){
350 dtypes[i] = 0;
351
352 switch( sym->type[i+1] ){
353 case 'p':
354 dtypes[i] = 'p';
355 case 'P':
356 {
357 struct ptr_data *data;
358 VALUE pval;
359
360 if( argv[i] == Qnil ){
361 ANY2P(args[i]) = DLVOIDP(0);
362 }
363 else{
364 if( rb_obj_is_kind_of(argv[i], rb_cDLPtrData) ){
365 pval = argv[i];
366 }
367 else{
368 pval = rb_funcall(argv[i], rb_intern("to_ptr"), 0);
369 if( !rb_obj_is_kind_of(pval, rb_cDLPtrData) ){
370 rb_raise(rb_eDLTypeError, "unexpected type of argument #%d", i);
371 };
372 };
373 Data_Get_Struct(pval, struct ptr_data, data);
374 ANY2P(args[i]) = DLVOIDP(data->ptr);
375 };
376 };
377 PUSH_P(ftype);
378 break;
379 case 'a':
380 dtypes[i] = 'a';
381 case 'A':
382 if( argv[i] == Qnil ){
383 ANY2P(args[i]) = DLVOIDP(0);
384 }
385 else{
386 ANY2P(args[i]) = DLVOIDP(rb_ary2cary(0, argv[i], NULL));
387 };
388 PUSH_P(ftype);
389 break;
390 case 'C':
391 ANY2C(args[i]) = DLCHAR(NUM2CHR(argv[i]));
392 PUSH_C(ftype);
393 break;
394 case 'c':
395 ANY2C(dargs[i]) = DLCHAR(NUM2CHR(argv[i]));
396 ANY2P(args[i]) = DLVOIDP(&(ANY2C(dargs[i])));
397 dtypes[i] = 'c';
398 PUSH_P(ftype);
399 break;
400 case 'H':
401 ANY2H(args[i]) = DLSHORT(NUM2CHR(argv[i]));
402 PUSH_C(ftype);
403 break;
404 case 'h':
405 ANY2H(dargs[i]) = DLSHORT(NUM2CHR(argv[i]));
406 ANY2P(args[i]) = DLVOIDP(&(ANY2H(dargs[i])));
407 dtypes[i] = 'h';
408 PUSH_P(ftype);
409 break;
410 case 'I':
411 ANY2I(args[i]) = DLINT(NUM2INT(argv[i]));
412 PUSH_I(ftype);
413 break;
414 case 'i':
415 ANY2I(dargs[i]) = DLINT(NUM2INT(argv[i]));
416 ANY2P(args[i]) = DLVOIDP(&(ANY2I(dargs[i])));
417 dtypes[i] = 'i';
418 PUSH_P(ftype);
419 break;
420 case 'L':
421 ANY2L(args[i]) = DLNUM2LONG(argv[i]);
422 PUSH_L(ftype);
423 break;
424 case 'l':
425 ANY2L(dargs[i]) = DLNUM2LONG(argv[i]);
426 ANY2P(args[i]) = DLVOIDP(&(ANY2L(dargs[i])));
427 dtypes[i] = 'l';
428 PUSH_P(ftype);
429 break;
430 case 'F':
431 Check_Type(argv[i], T_FLOAT);
432 ANY2F(args[i]) = DLFLOAT(RFLOAT(argv[i])->value);
433 PUSH_F(ftype);
434 break;
435 case 'f':
436 Check_Type(argv[i], T_FLOAT);
437 ANY2F(dargs[i]) = DLFLOAT(RFLOAT(argv[i])->value);
438 ANY2P(args[i]) = DLVOIDP(&(ANY2F(dargs[i])));
439 dtypes[i] = 'f';
440 PUSH_P(ftype);
441 break;
442 case 'D':
443 Check_Type(argv[i], T_FLOAT);
444 ANY2D(args[i]) = RFLOAT(argv[i])->value;
445 PUSH_D(ftype);
446 break;
447 case 'd':
448 Check_Type(argv[i], T_FLOAT);
449 ANY2D(dargs[i]) = RFLOAT(argv[i])->value;
450 ANY2P(args[i]) = DLVOIDP(&(ANY2D(dargs[i])));
451 dtypes[i] = 'd';
452 PUSH_P(ftype);
453 break;
454 case 'S':
455 if( argv[i] == Qnil ){
456 ANY2S(args[i]) = DLSTR(0);
457 }
458 else{
459 if( TYPE(argv[i]) != T_STRING ){
460 rb_raise(rb_eDLError, "#%d must be a string",i);
461 };
462 ANY2S(args[i]) = DLSTR(RSTRING(argv[i])->ptr);
463 };
464 PUSH_P(ftype);
465 break;
466 case 's':
467 if( TYPE(argv[i]) != T_STRING ){
468 rb_raise(rb_eDLError, "#%d must be a string",i);
469 };
470 ANY2S(args[i]) = DLSTR(dlmalloc(RSTRING(argv[i])->len + 1));
471 memcpy((char*)(ANY2S(args[i])), RSTRING(argv[i])->ptr, RSTRING(argv[i])->len + 1);
472 dtypes[i] = 's';
473 PUSH_P(ftype);
474 break;
475 default:
476 FREE_ARGS;
477 rb_raise(rb_eDLTypeError,
478 "unknown type '%c' of the return value.",
479 sym->type[i+1]);
480 };
481 };
482
483 switch( sym->type[0] ){
484 case '0':
485 PUSH_0(ftype);
486 break;
487 case 'P':
488 case 'p':
489 case 'S':
490 case 's':
491 case 'A':
492 case 'a':
493 PUSH_P(ftype);
494 break;
495 case 'C':
496 case 'c':
497 PUSH_C(ftype);
498 break;
499 case 'H':
500 case 'h':
501 PUSH_H(ftype);
502 break;
503 case 'I':
504 case 'i':
505 PUSH_I(ftype);
506 break;
507 case 'L':
508 case 'l':
509 PUSH_L(ftype);
510 break;
511 case 'F':
512 case 'f':
513 PUSH_F(ftype);
514 break;
515 case 'D':
516 case 'd':
517 PUSH_D(ftype);
518 break;
519 default:
520 FREE_ARGS;
521 rb_raise(rb_eDLTypeError,
522 "unknown type `%c' of the return value.",
523 sym->type[0]);
524 };
525
526 func = sym->func;
527
528 #if defined(DLSTACK)
529 {
530 #if defined(DLSTACK_SIZE)
531 int stk_size;
532 long stack[DLSTACK_SIZE];
533 long *sp;
534
535 sp = stack;
536 stk_size = stack_size(sym);
537 if( stk_size < 0 ){
538 FREE_ARGS;
539 rb_raise(rb_eDLTypeError, "unknown type '%c'.", -stk_size);
540 }
541 else if( stk_size > (int)(DLSTACK_SIZE) ){
542 FREE_ARGS;
543 rb_raise(rb_eArgError, "too many arguments.");
544 }
545 #endif
546
547 DLSTACK_START(sym);
548
549 #if defined(DLSTACK_REVERSE)
550 for( i = sym->len - 2; i >= 0; i-- )
551 #else
552 for( i = 0; i <= sym->len -2; i++ )
553 #endif
554 {
555 switch( sym->type[i+1] ){
556 case 'p':
557 case 'P':
558 DLSTACK_PUSH_P(ANY2P(args[i]));
559 break;
560 case 'a':
561 case 'A':
562 DLSTACK_PUSH_P(ANY2P(args[i]));
563 break;
564 case 'C':
565 DLSTACK_PUSH_C(ANY2C(args[i]));
566 break;
567 case 'c':
568 DLSTACK_PUSH_P(ANY2P(args[i]));
569 break;
570 case 'H':
571 DLSTACK_PUSH_H(ANY2H(args[i]));
572 break;
573 case 'h':
574 DLSTACK_PUSH_P(ANY2P(args[i]));
575 break;
576 case 'I':
577 DLSTACK_PUSH_I(ANY2I(args[i]));
578 break;
579 case 'i':
580 DLSTACK_PUSH_P(ANY2P(args[i]));
581 break;
582 case 'L':
583 DLSTACK_PUSH_L(ANY2L(args[i]));
584 break;
585 case 'l':
586 DLSTACK_PUSH_P(ANY2P(args[i]));
587 break;
588 case 'F':
589 DLSTACK_PUSH_F(ANY2F(args[i]));
590 break;
591 case 'f':
592 DLSTACK_PUSH_P(ANY2P(args[i]));
593 break;
594 case 'D':
595 DLSTACK_PUSH_D(ANY2D(args[i]));
596 break;
597 case 'd':
598 DLSTACK_PUSH_P(ANY2P(args[i]));
599 break;
600 case 'S':
601 case 's':
602 DLSTACK_PUSH_P(ANY2S(args[i]));
603 break;
604 };
605 }
606 DLSTACK_END(sym->type);
607
608 {
609 switch( sym->type[0] ){
610 case '0':
611 {
612 void (*f)(DLSTACK_PROTO) = func;
613 f(DLSTACK_ARGS);
614 };
615 break;
616 case 'P':
617 case 'p':
618 {
619 void * (*f)(DLSTACK_PROTO) = func;
620 ret.p = f(DLSTACK_ARGS);
621 };
622 break;
623 case 'C':
624 case 'c':
625 {
626 char (*f)(DLSTACK_PROTO) = func;
627 ret.c = f(DLSTACK_ARGS);
628 };
629 break;
630 case 'H':
631 case 'h':
632 {
633 short (*f)(DLSTACK_PROTO) = func;
634 ret.h = f(DLSTACK_ARGS);
635 };
636 break;
637 case 'I':
638 case 'i':
639 {
640 int (*f)(DLSTACK_PROTO) = func;
641 ret.i = f(DLSTACK_ARGS);
642 };
643 break;
644 case 'L':
645 case 'l':
646 {
647 long (*f)(DLSTACK_PROTO) = func;
648 ret.l = f(DLSTACK_ARGS);
649 };
650 break;
651 case 'F':
652 case 'f':
653 {
654 float (*f)(DLSTACK_PROTO) = func;
655 ret.f = f(DLSTACK_ARGS);
656 };
657 break;
658 case 'D':
659 case 'd':
660 {
661 double (*f)(DLSTACK_PROTO) = func;
662 ret.d = f(DLSTACK_ARGS);
663 };
664 break;
665 case 'S':
666 case 's':
667 {
668 char * (*f)(DLSTACK_PROTO) = func;
669 ret.s = f(DLSTACK_ARGS);
670 };
671 break;
672 default:
673 FREE_ARGS;
674 rb_raise(rb_eDLTypeError, "unknown type `%c'", sym->type[0]);
675 }
676 }
677 }
678 #else
679 switch(ftype){
680 #include "call.func"
681 default:
682 FREE_ARGS;
683 rb_raise(rb_eDLTypeError, "unsupported function type `%s'", sym->type);
684 };
685 #endif
686
687 switch( sym->type[0] ){
688 case '0':
689 val = Qnil;
690 break;
691 case 'P':
692 val = rb_dlptr_new((void*)(ANY2P(ret)), 0, 0);
693 break;
694 case 'p':
695 val = rb_dlptr_new((void*)(ANY2P(ret)), 0, dlfree);
696 break;
697 case 'C':
698 case 'c':
699 val = CHR2FIX((char)(ANY2C(ret)));
700 break;
701 case 'H':
702 case 'h':
703 val = INT2NUM((short)(ANY2H(ret)));
704 break;
705 case 'I':
706 case 'i':
707 val = INT2NUM((int)(ANY2I(ret)));
708 break;
709 case 'L':
710 case 'l':
711 val = DLLONG2NUM((long)(ANY2L(ret)));
712 break;
713 case 'F':
714 case 'f':
715 val = rb_float_new((double)(ANY2F(ret)));
716 break;
717 case 'D':
718 case 'd':
719 val = rb_float_new((double)(ANY2D(ret)));
720 break;
721 case 'S':
722 if( ANY2S(ret) ){
723 val = rb_tainted_str_new2((char*)(ANY2S(ret)));
724 }
725 else{
726 val = Qnil;
727 };
728 break;
729 case 's':
730 if( ANY2S(ret) ){
731 val = rb_tainted_str_new2((char*)(ANY2S(ret)));
732 DEBUG_CODE({
733 printf("dlfree(%s)\n",(char*)(ANY2S(ret)));
734 });
735 dlfree((void*)(ANY2S(ret)));
736 }
737 else{
738 val = Qnil;
739 };
740 break;
741 default:
742 FREE_ARGS;
743 rb_raise(rb_eDLTypeError, "unknown type `%c'", sym->type[0]);
744 };
745
746 dvals = rb_ary_new();
747 for( i = 0; i <= sym->len - 2; i++ ){
748 if( dtypes[i] ){
749 switch( dtypes[i] ){
750 case 'c':
751 rb_ary_push(dvals, CHR2FIX(*((char*)(ANY2P(args[i])))));
752 break;
753 case 'h':
754 rb_ary_push(dvals, INT2NUM(*((short*)(ANY2P(args[i])))));
755 break;
756 case 'i':
757 rb_ary_push(dvals, INT2NUM(*((int*)(ANY2P(args[i])))));
758 break;
759 case 'l':
760 rb_ary_push(dvals, DLLONG2NUM(*((long*)(ANY2P(args[i])))));
761 break;
762 case 'f':
763 rb_ary_push(dvals, rb_float_new(*((float*)(ANY2P(args[i])))));
764 break;
765 case 'd':
766 rb_ary_push(dvals, rb_float_new(*((double*)(ANY2P(args[i])))));
767 break;
768 case 'p':
769 rb_ary_push(dvals, rb_dlptr_new((void*)(ANY2P(args[i])), 0, 0));
770 break;
771 case 'a':
772 rb_ary_push(dvals, rb_dlptr_new((void*)ANY2P(args[i]), 0, 0));
773 break;
774 case 's':
775 rb_ary_push(dvals, rb_tainted_str_new2((char*)ANY2S(args[i])));
776 DEBUG_CODE({
777 printf("dlfree(%s)\n",(char*)ANY2S(args[i]));
778 });
779 dlfree((void*)ANY2S(args[i]));
780 break;
781 default:
782 {
783 char c = dtypes[i];
784 FREE_ARGS;
785 rb_raise(rb_eRuntimeError, "unknown argument type '%c'", i, c);
786 };
787 };
788 }
789 else{
790 switch( sym->type[i+1] ){
791 case 'A':
792 dlfree((void*)ANY2P(args[i]));
793 break;
794 };
795 rb_ary_push(dvals, argv[i]);
796 };
797 };
798
799 #undef FREE_ARGS
800 return rb_assoc_new(val,dvals);
801 }
802
803 VALUE
804 rb_dlsym_to_i(VALUE self)
805 {
806 struct sym_data *sym;
807
808 Data_Get_Struct(self, struct sym_data, sym);
809 return DLLONG2NUM(sym);
810 }
811
812 VALUE
813 rb_dlsym_to_ptr(VALUE self)
814 {
815 struct sym_data *sym;
816
817 Data_Get_Struct(self, struct sym_data, sym);
818 return rb_dlptr_new(sym->func, sizeof(freefunc_t), 0);
819 }
820
821 void
822 Init_dlsym()
823 {
824 rb_cDLSymbol = rb_define_class_under(rb_mDL, "Symbol", rb_cObject);
825 rb_define_singleton_method(rb_cDLSymbol, "allocate", rb_dlsym_s_allocate, 0);
826 rb_define_singleton_method(rb_cDLSymbol, "char2type", rb_s_dlsym_char2type, 1);
827 rb_define_method(rb_cDLSymbol, "initialize", rb_dlsym_initialize, -1);
828 rb_define_method(rb_cDLSymbol, "call", rb_dlsym_call, -1);
829 rb_define_method(rb_cDLSymbol, "[]", rb_dlsym_call, -1);
830 rb_define_method(rb_cDLSymbol, "name", rb_dlsym_name, 0);
831 rb_define_method(rb_cDLSymbol, "proto", rb_dlsym_proto, 0);
832 rb_define_method(rb_cDLSymbol, "cproto", rb_dlsym_cproto, 0);
833 rb_define_method(rb_cDLSymbol, "inspect", rb_dlsym_inspect, 0);
834 rb_define_method(rb_cDLSymbol, "to_s", rb_dlsym_cproto, 0);
835 rb_define_method(rb_cDLSymbol, "to_ptr", rb_dlsym_to_ptr, 0);
836 rb_define_method(rb_cDLSymbol, "to_i", rb_dlsym_to_i, 0);
837 }