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