Ruby 1.9.3p327(2012-11-10revision37606)
ext/dl/cfunc.c
Go to the documentation of this file.
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