Ruby 1.9.3p327(2012-11-10revision37606)
|
00001 /* -*- C -*- 00002 * $Id: cfunc.c 37007 2012-09-21 10:53:50Z naruse $ 00003 */ 00004 00005 #include <ruby.h> 00006 #include <errno.h> 00007 #include "dl.h" 00008 00009 VALUE rb_cDLCFunc; 00010 00011 static ID id_last_error; 00012 00013 static VALUE 00014 rb_dl_get_last_error(VALUE self) 00015 { 00016 return rb_thread_local_aref(rb_thread_current(), id_last_error); 00017 } 00018 00019 static VALUE 00020 rb_dl_set_last_error(VALUE self, VALUE val) 00021 { 00022 rb_thread_local_aset(rb_thread_current(), id_last_error, val); 00023 return Qnil; 00024 } 00025 00026 #if defined(_WIN32) 00027 #include <windows.h> 00028 static ID id_win32_last_error; 00029 00030 static VALUE 00031 rb_dl_get_win32_last_error(VALUE self) 00032 { 00033 return rb_thread_local_aref(rb_thread_current(), id_win32_last_error); 00034 } 00035 00036 static VALUE 00037 rb_dl_set_win32_last_error(VALUE self, VALUE val) 00038 { 00039 rb_thread_local_aset(rb_thread_current(), id_win32_last_error, val); 00040 return Qnil; 00041 } 00042 #endif 00043 00044 static void 00045 dlcfunc_mark(void *ptr) 00046 { 00047 struct cfunc_data *data = ptr; 00048 if (data->wrap) { 00049 rb_gc_mark(data->wrap); 00050 } 00051 } 00052 00053 static void 00054 dlcfunc_free(void *ptr) 00055 { 00056 struct cfunc_data *data = ptr; 00057 if( data->name ){ 00058 xfree(data->name); 00059 } 00060 xfree(data); 00061 } 00062 00063 static size_t 00064 dlcfunc_memsize(const void *ptr) 00065 { 00066 const struct cfunc_data *data = ptr; 00067 size_t size = 0; 00068 if( data ){ 00069 size += sizeof(*data); 00070 if( data->name ){ 00071 size += strlen(data->name) + 1; 00072 } 00073 } 00074 return size; 00075 } 00076 00077 const rb_data_type_t dlcfunc_data_type = { 00078 "dl/cfunc", 00079 {dlcfunc_mark, dlcfunc_free, dlcfunc_memsize,}, 00080 }; 00081 00082 VALUE 00083 rb_dlcfunc_new(void (*func)(), int type, const char *name, ID calltype) 00084 { 00085 VALUE val; 00086 struct cfunc_data *data; 00087 00088 rb_secure(4); 00089 if( func ){ 00090 val = TypedData_Make_Struct(rb_cDLCFunc, struct cfunc_data, &dlcfunc_data_type, data); 00091 data->ptr = (void *)(VALUE)func; 00092 data->name = name ? strdup(name) : NULL; 00093 data->type = type; 00094 data->calltype = calltype; 00095 } 00096 else{ 00097 val = Qnil; 00098 } 00099 00100 return val; 00101 } 00102 00103 void * 00104 rb_dlcfunc2ptr(VALUE val) 00105 { 00106 struct cfunc_data *data; 00107 void * func; 00108 00109 if( rb_typeddata_is_kind_of(val, &dlcfunc_data_type) ){ 00110 data = DATA_PTR(val); 00111 func = data->ptr; 00112 } 00113 else if( val == Qnil ){ 00114 func = NULL; 00115 } 00116 else{ 00117 rb_raise(rb_eTypeError, "DL::CFunc was expected"); 00118 } 00119 00120 return func; 00121 } 00122 00123 static VALUE 00124 rb_dlcfunc_s_allocate(VALUE klass) 00125 { 00126 VALUE obj; 00127 struct cfunc_data *data; 00128 00129 obj = TypedData_Make_Struct(klass, struct cfunc_data, &dlcfunc_data_type, data); 00130 data->ptr = 0; 00131 data->name = 0; 00132 data->type = 0; 00133 data->calltype = CFUNC_CDECL; 00134 00135 return obj; 00136 } 00137 00138 int 00139 rb_dlcfunc_kind_p(VALUE func) 00140 { 00141 return rb_typeddata_is_kind_of(func, &dlcfunc_data_type); 00142 } 00143 00144 /* 00145 * call-seq: 00146 * DL::CFunc.new(address, type=DL::TYPE_VOID, name=nil, calltype=:cdecl) 00147 * 00148 * Create a new function that points to +address+ with an optional return type 00149 * of +type+, a name of +name+ and a calltype of +calltype+. 00150 */ 00151 static VALUE 00152 rb_dlcfunc_initialize(int argc, VALUE argv[], VALUE self) 00153 { 00154 VALUE addr, name, type, calltype, addrnum; 00155 struct cfunc_data *data; 00156 void *saddr; 00157 const char *sname; 00158 00159 rb_scan_args(argc, argv, "13", &addr, &type, &name, &calltype); 00160 00161 addrnum = rb_Integer(addr); 00162 saddr = (void*)(NUM2PTR(addrnum)); 00163 sname = NIL_P(name) ? NULL : StringValuePtr(name); 00164 00165 TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, data); 00166 if( data->name ) xfree(data->name); 00167 data->ptr = saddr; 00168 data->name = sname ? strdup(sname) : 0; 00169 data->type = NIL_P(type) ? DLTYPE_VOID : NUM2INT(type); 00170 data->calltype = NIL_P(calltype) ? CFUNC_CDECL : SYM2ID(calltype); 00171 data->wrap = (addrnum == addr) ? 0 : addr; 00172 00173 return Qnil; 00174 } 00175 00176 /* 00177 * call-seq: 00178 * name => str 00179 * 00180 * Get the name of this function 00181 */ 00182 static VALUE 00183 rb_dlcfunc_name(VALUE self) 00184 { 00185 struct cfunc_data *cfunc; 00186 00187 TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc); 00188 return cfunc->name ? rb_tainted_str_new2(cfunc->name) : Qnil; 00189 } 00190 00191 /* 00192 * call-seq: 00193 * cfunc.ctype => num 00194 * 00195 * Get the C function return value type. See DL for a list of constants 00196 * corresponding to this method's return value. 00197 */ 00198 static VALUE 00199 rb_dlcfunc_ctype(VALUE self) 00200 { 00201 struct cfunc_data *cfunc; 00202 00203 TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc); 00204 return INT2NUM(cfunc->type); 00205 } 00206 00207 /* 00208 * call-seq: 00209 * cfunc.ctype = type 00210 * 00211 * Set the C function return value type to +type+. 00212 */ 00213 static VALUE 00214 rb_dlcfunc_set_ctype(VALUE self, VALUE ctype) 00215 { 00216 struct cfunc_data *cfunc; 00217 00218 TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc); 00219 cfunc->type = NUM2INT(ctype); 00220 return ctype; 00221 } 00222 00223 /* 00224 * call-seq: 00225 * cfunc.calltype => symbol 00226 * 00227 * Get the call type of this function. 00228 */ 00229 static VALUE 00230 rb_dlcfunc_calltype(VALUE self) 00231 { 00232 struct cfunc_data *cfunc; 00233 00234 TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc); 00235 return ID2SYM(cfunc->calltype); 00236 } 00237 00238 /* 00239 * call-seq: 00240 * cfunc.calltype = symbol 00241 * 00242 * Set the call type for this function. 00243 */ 00244 static VALUE 00245 rb_dlcfunc_set_calltype(VALUE self, VALUE sym) 00246 { 00247 struct cfunc_data *cfunc; 00248 00249 TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc); 00250 cfunc->calltype = SYM2ID(sym); 00251 return sym; 00252 } 00253 00254 /* 00255 * call-seq: 00256 * cfunc.ptr 00257 * 00258 * Get the underlying function pointer as a DL::CPtr object. 00259 */ 00260 static VALUE 00261 rb_dlcfunc_ptr(VALUE self) 00262 { 00263 struct cfunc_data *cfunc; 00264 00265 TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc); 00266 return PTR2NUM(cfunc->ptr); 00267 } 00268 00269 /* 00270 * call-seq: 00271 * cfunc.ptr = pointer 00272 * 00273 * Set the underlying function pointer to a DL::CPtr named +pointer+. 00274 */ 00275 static VALUE 00276 rb_dlcfunc_set_ptr(VALUE self, VALUE addr) 00277 { 00278 struct cfunc_data *cfunc; 00279 00280 TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc); 00281 cfunc->ptr = NUM2PTR(addr); 00282 00283 return Qnil; 00284 } 00285 00286 /* 00287 * call-seq: inspect 00288 * 00289 * Returns a string formatted with an easily readable representation of the 00290 * internal state of the DL::CFunc 00291 */ 00292 static VALUE 00293 rb_dlcfunc_inspect(VALUE self) 00294 { 00295 VALUE val; 00296 struct cfunc_data *cfunc; 00297 00298 TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc); 00299 00300 val = rb_sprintf("#<DL::CFunc:%p ptr=%p type=%d name='%s'>", 00301 cfunc, 00302 cfunc->ptr, 00303 cfunc->type, 00304 cfunc->name ? cfunc->name : ""); 00305 OBJ_TAINT(val); 00306 return val; 00307 } 00308 00309 00310 # define DECL_FUNC_CDECL(f,ret,args,val) \ 00311 ret (FUNC_CDECL(*(f)))(args) = (ret (FUNC_CDECL(*))(args))(VALUE)(val) 00312 #ifdef FUNC_STDCALL 00313 # define DECL_FUNC_STDCALL(f,ret,args,val) \ 00314 ret (FUNC_STDCALL(*(f)))(args) = (ret (FUNC_STDCALL(*))(args))(VALUE)(val) 00315 #endif 00316 00317 #define CALL_CASE switch( RARRAY_LEN(ary) ){ \ 00318 CASE(0); break; \ 00319 CASE(1); break; CASE(2); break; CASE(3); break; CASE(4); break; CASE(5); break; \ 00320 CASE(6); break; CASE(7); break; CASE(8); break; CASE(9); break; CASE(10);break; \ 00321 CASE(11);break; CASE(12);break; CASE(13);break; CASE(14);break; CASE(15);break; \ 00322 CASE(16);break; CASE(17);break; CASE(18);break; CASE(19);break; CASE(20);break; \ 00323 default: rb_raise(rb_eArgError, "too many arguments"); \ 00324 } 00325 00326 00327 #if defined(_MSC_VER) && defined(_M_AMD64) && _MSC_VER >= 1400 && _MSC_VER < 1600 00328 # pragma optimize("", off) 00329 #endif 00330 /* 00331 * call-seq: 00332 * dlcfunc.call(ary) => some_value 00333 * dlcfunc[ary] => some_value 00334 * 00335 * Calls the function pointer passing in +ary+ as values to the underlying 00336 * C function. The return value depends on the ctype. 00337 */ 00338 static VALUE 00339 rb_dlcfunc_call(VALUE self, VALUE ary) 00340 { 00341 struct cfunc_data *cfunc; 00342 int i; 00343 DLSTACK_TYPE stack[DLSTACK_SIZE]; 00344 VALUE result = Qnil; 00345 00346 rb_secure_update(self); 00347 00348 memset(stack, 0, sizeof(DLSTACK_TYPE) * DLSTACK_SIZE); 00349 Check_Type(ary, T_ARRAY); 00350 00351 TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc); 00352 00353 if( cfunc->ptr == 0 ){ 00354 rb_raise(rb_eDLError, "can't call null-function"); 00355 return Qnil; 00356 } 00357 00358 for( i = 0; i < RARRAY_LEN(ary); i++ ){ 00359 VALUE arg; 00360 if( i >= DLSTACK_SIZE ){ 00361 rb_raise(rb_eDLError, "too many arguments (stack overflow)"); 00362 } 00363 arg = rb_to_int(RARRAY_PTR(ary)[i]); 00364 rb_check_safe_obj(arg); 00365 if (FIXNUM_P(arg)) { 00366 stack[i] = (DLSTACK_TYPE)FIX2LONG(arg); 00367 } 00368 else if (RB_TYPE_P(arg, T_BIGNUM)) { 00369 #if SIZEOF_VOIDP == SIZEOF_LONG 00370 stack[i] = (DLSTACK_TYPE)rb_big2ulong_pack(arg); 00371 #else 00372 stack[i] = (DLSTACK_TYPE)rb_big2ull(arg); 00373 #endif 00374 } 00375 else { 00376 Check_Type(arg, T_FIXNUM); 00377 } 00378 } 00379 00380 /* calltype == CFUNC_CDECL */ 00381 if( cfunc->calltype == CFUNC_CDECL 00382 #ifndef FUNC_STDCALL 00383 || cfunc->calltype == CFUNC_STDCALL 00384 #endif 00385 ){ 00386 switch( cfunc->type ){ 00387 case DLTYPE_VOID: 00388 #define CASE(n) case n: { \ 00389 DECL_FUNC_CDECL(f,void,DLSTACK_PROTO##n,cfunc->ptr); \ 00390 f(DLSTACK_ARGS##n(stack)); \ 00391 result = Qnil; \ 00392 } 00393 CALL_CASE; 00394 #undef CASE 00395 break; 00396 case DLTYPE_VOIDP: 00397 #define CASE(n) case n: { \ 00398 DECL_FUNC_CDECL(f,void*,DLSTACK_PROTO##n,cfunc->ptr); \ 00399 void * ret; \ 00400 ret = f(DLSTACK_ARGS##n(stack)); \ 00401 result = PTR2NUM(ret); \ 00402 } 00403 CALL_CASE; 00404 #undef CASE 00405 break; 00406 case DLTYPE_CHAR: 00407 #define CASE(n) case n: { \ 00408 DECL_FUNC_CDECL(f,char,DLSTACK_PROTO##n,cfunc->ptr); \ 00409 char ret; \ 00410 ret = f(DLSTACK_ARGS##n(stack)); \ 00411 result = CHR2FIX(ret); \ 00412 } 00413 CALL_CASE; 00414 #undef CASE 00415 break; 00416 case DLTYPE_SHORT: 00417 #define CASE(n) case n: { \ 00418 DECL_FUNC_CDECL(f,short,DLSTACK_PROTO##n,cfunc->ptr); \ 00419 short ret; \ 00420 ret = f(DLSTACK_ARGS##n(stack)); \ 00421 result = INT2NUM((int)ret); \ 00422 } 00423 CALL_CASE; 00424 #undef CASE 00425 break; 00426 case DLTYPE_INT: 00427 #define CASE(n) case n: { \ 00428 DECL_FUNC_CDECL(f,int,DLSTACK_PROTO##n,cfunc->ptr); \ 00429 int ret; \ 00430 ret = f(DLSTACK_ARGS##n(stack)); \ 00431 result = INT2NUM(ret); \ 00432 } 00433 CALL_CASE; 00434 #undef CASE 00435 break; 00436 case DLTYPE_LONG: 00437 #define CASE(n) case n: { \ 00438 DECL_FUNC_CDECL(f,long,DLSTACK_PROTO##n,cfunc->ptr); \ 00439 long ret; \ 00440 ret = f(DLSTACK_ARGS##n(stack)); \ 00441 result = LONG2NUM(ret); \ 00442 } 00443 CALL_CASE; 00444 #undef CASE 00445 break; 00446 #if HAVE_LONG_LONG /* used in ruby.h */ 00447 case DLTYPE_LONG_LONG: 00448 #define CASE(n) case n: { \ 00449 DECL_FUNC_CDECL(f,LONG_LONG,DLSTACK_PROTO##n,cfunc->ptr); \ 00450 LONG_LONG ret; \ 00451 ret = f(DLSTACK_ARGS##n(stack)); \ 00452 result = LL2NUM(ret); \ 00453 } 00454 CALL_CASE; 00455 #undef CASE 00456 break; 00457 #endif 00458 case DLTYPE_FLOAT: 00459 #define CASE(n) case n: { \ 00460 DECL_FUNC_CDECL(f,float,DLSTACK_PROTO##n,cfunc->ptr); \ 00461 float ret; \ 00462 ret = f(DLSTACK_ARGS##n(stack)); \ 00463 result = rb_float_new(ret); \ 00464 } 00465 CALL_CASE; 00466 #undef CASE 00467 break; 00468 case DLTYPE_DOUBLE: 00469 #define CASE(n) case n: { \ 00470 DECL_FUNC_CDECL(f,double,DLSTACK_PROTO##n,cfunc->ptr); \ 00471 double ret; \ 00472 ret = f(DLSTACK_ARGS##n(stack)); \ 00473 result = rb_float_new(ret); \ 00474 } 00475 CALL_CASE; 00476 #undef CASE 00477 break; 00478 default: 00479 rb_raise(rb_eDLTypeError, "unknown type %d", cfunc->type); 00480 } 00481 } 00482 #ifdef FUNC_STDCALL 00483 else if( cfunc->calltype == CFUNC_STDCALL ){ 00484 /* calltype == CFUNC_STDCALL */ 00485 switch( cfunc->type ){ 00486 case DLTYPE_VOID: 00487 #define CASE(n) case n: { \ 00488 DECL_FUNC_STDCALL(f,void,DLSTACK_PROTO##n##_,cfunc->ptr); \ 00489 f(DLSTACK_ARGS##n(stack)); \ 00490 result = Qnil; \ 00491 } 00492 CALL_CASE; 00493 #undef CASE 00494 break; 00495 case DLTYPE_VOIDP: 00496 #define CASE(n) case n: { \ 00497 DECL_FUNC_STDCALL(f,void*,DLSTACK_PROTO##n##_,cfunc->ptr); \ 00498 void * ret; \ 00499 ret = f(DLSTACK_ARGS##n(stack)); \ 00500 result = PTR2NUM(ret); \ 00501 } 00502 CALL_CASE; 00503 #undef CASE 00504 break; 00505 case DLTYPE_CHAR: 00506 #define CASE(n) case n: { \ 00507 DECL_FUNC_STDCALL(f,char,DLSTACK_PROTO##n##_,cfunc->ptr); \ 00508 char ret; \ 00509 ret = f(DLSTACK_ARGS##n(stack)); \ 00510 result = CHR2FIX(ret); \ 00511 } 00512 CALL_CASE; 00513 #undef CASE 00514 break; 00515 case DLTYPE_SHORT: 00516 #define CASE(n) case n: { \ 00517 DECL_FUNC_STDCALL(f,short,DLSTACK_PROTO##n##_,cfunc->ptr); \ 00518 short ret; \ 00519 ret = f(DLSTACK_ARGS##n(stack)); \ 00520 result = INT2NUM((int)ret); \ 00521 } 00522 CALL_CASE; 00523 #undef CASE 00524 break; 00525 case DLTYPE_INT: 00526 #define CASE(n) case n: { \ 00527 DECL_FUNC_STDCALL(f,int,DLSTACK_PROTO##n##_,cfunc->ptr); \ 00528 int ret; \ 00529 ret = f(DLSTACK_ARGS##n(stack)); \ 00530 result = INT2NUM(ret); \ 00531 } 00532 CALL_CASE; 00533 #undef CASE 00534 break; 00535 case DLTYPE_LONG: 00536 #define CASE(n) case n: { \ 00537 DECL_FUNC_STDCALL(f,long,DLSTACK_PROTO##n##_,cfunc->ptr); \ 00538 long ret; \ 00539 ret = f(DLSTACK_ARGS##n(stack)); \ 00540 result = LONG2NUM(ret); \ 00541 } 00542 CALL_CASE; 00543 #undef CASE 00544 break; 00545 #if HAVE_LONG_LONG /* used in ruby.h */ 00546 case DLTYPE_LONG_LONG: 00547 #define CASE(n) case n: { \ 00548 DECL_FUNC_STDCALL(f,LONG_LONG,DLSTACK_PROTO##n##_,cfunc->ptr); \ 00549 LONG_LONG ret; \ 00550 ret = f(DLSTACK_ARGS##n(stack)); \ 00551 result = LL2NUM(ret); \ 00552 } 00553 CALL_CASE; 00554 #undef CASE 00555 break; 00556 #endif 00557 case DLTYPE_FLOAT: 00558 #define CASE(n) case n: { \ 00559 DECL_FUNC_STDCALL(f,float,DLSTACK_PROTO##n##_,cfunc->ptr); \ 00560 float ret; \ 00561 ret = f(DLSTACK_ARGS##n(stack)); \ 00562 result = rb_float_new(ret); \ 00563 } 00564 CALL_CASE; 00565 #undef CASE 00566 break; 00567 case DLTYPE_DOUBLE: 00568 #define CASE(n) case n: { \ 00569 DECL_FUNC_STDCALL(f,double,DLSTACK_PROTO##n##_,cfunc->ptr); \ 00570 double ret; \ 00571 ret = f(DLSTACK_ARGS##n(stack)); \ 00572 result = rb_float_new(ret); \ 00573 } 00574 CALL_CASE; 00575 #undef CASE 00576 break; 00577 default: 00578 rb_raise(rb_eDLTypeError, "unknown type %d", cfunc->type); 00579 } 00580 } 00581 #endif 00582 else{ 00583 const char *name = rb_id2name(cfunc->calltype); 00584 if( name ){ 00585 rb_raise(rb_eDLError, "unsupported call type: %s", 00586 name); 00587 } 00588 else{ 00589 rb_raise(rb_eDLError, "unsupported call type: %"PRIxVALUE, 00590 cfunc->calltype); 00591 } 00592 } 00593 00594 rb_dl_set_last_error(self, INT2NUM(errno)); 00595 #if defined(_WIN32) 00596 rb_dl_set_win32_last_error(self, INT2NUM(GetLastError())); 00597 #endif 00598 00599 return result; 00600 } 00601 #if defined(_MSC_VER) && defined(_M_AMD64) && _MSC_VER >= 1400 && _MSC_VER < 1600 00602 # pragma optimize("", on) 00603 #endif 00604 00605 /* 00606 * call-seq: 00607 * dlfunc.to_i => integer 00608 * 00609 * Returns the memory location of this function pointer as an integer. 00610 */ 00611 static VALUE 00612 rb_dlcfunc_to_i(VALUE self) 00613 { 00614 struct cfunc_data *cfunc; 00615 00616 TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc); 00617 return PTR2NUM(cfunc->ptr); 00618 } 00619 00620 void 00621 Init_dlcfunc(void) 00622 { 00623 id_last_error = rb_intern("__DL2_LAST_ERROR__"); 00624 #if defined(_WIN32) 00625 id_win32_last_error = rb_intern("__DL2_WIN32_LAST_ERROR__"); 00626 #endif 00627 00628 /* 00629 * Document-class: DL::CFunc 00630 * 00631 * A direct accessor to a function in a C library 00632 * 00633 * == Example 00634 * 00635 * libc_so = "/lib64/libc.so.6" 00636 * => "/lib64/libc.so.6" 00637 * libc = DL::dlopen(libc_so) 00638 * => #<DL::Handle:0x00000000e05b00> 00639 * @cfunc = DL::CFunc.new(libc,['strcpy'], DL::TYPE_VOIDP, 'strcpy') 00640 * => #<DL::CFunc:0x000000012daec0 ptr=0x007f62ca5a8300 type=1 name='strcpy'> 00641 * 00642 */ 00643 rb_cDLCFunc = rb_define_class_under(rb_mDL, "CFunc", rb_cObject); 00644 rb_define_alloc_func(rb_cDLCFunc, rb_dlcfunc_s_allocate); 00645 00646 /* 00647 * Document-method: last_error 00648 * 00649 * Returns the last error for the current executing thread 00650 */ 00651 rb_define_module_function(rb_cDLCFunc, "last_error", rb_dl_get_last_error, 0); 00652 #if defined(_WIN32) 00653 00654 /* 00655 * Document-method: win32_last_error 00656 * 00657 * Returns the last win32 error for the current executing thread 00658 */ 00659 rb_define_module_function(rb_cDLCFunc, "win32_last_error", rb_dl_get_win32_last_error, 0); 00660 #endif 00661 rb_define_method(rb_cDLCFunc, "initialize", rb_dlcfunc_initialize, -1); 00662 rb_define_method(rb_cDLCFunc, "call", rb_dlcfunc_call, 1); 00663 rb_define_method(rb_cDLCFunc, "[]", rb_dlcfunc_call, 1); 00664 rb_define_method(rb_cDLCFunc, "name", rb_dlcfunc_name, 0); 00665 rb_define_method(rb_cDLCFunc, "ctype", rb_dlcfunc_ctype, 0); 00666 rb_define_method(rb_cDLCFunc, "ctype=", rb_dlcfunc_set_ctype, 1); 00667 rb_define_method(rb_cDLCFunc, "calltype", rb_dlcfunc_calltype, 0); 00668 rb_define_method(rb_cDLCFunc, "calltype=", rb_dlcfunc_set_calltype, 1); 00669 rb_define_method(rb_cDLCFunc, "ptr", rb_dlcfunc_ptr, 0); 00670 rb_define_method(rb_cDLCFunc, "ptr=", rb_dlcfunc_set_ptr, 1); 00671 rb_define_method(rb_cDLCFunc, "inspect", rb_dlcfunc_inspect, 0); 00672 rb_define_method(rb_cDLCFunc, "to_s", rb_dlcfunc_inspect, 0); 00673 rb_define_method(rb_cDLCFunc, "to_i", rb_dlcfunc_to_i, 0); 00674 } 00675