Ruby 1.9.2p136(2010-12-25revision30365)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

# ext/dl/cfunc.c

Go to the documentation of this file.

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