00001 #include <ruby/ruby.h>
00002 #include <ruby/io.h>
00003 #include <ctype.h>
00004 #include "dl.h"
00005
00006 VALUE rb_mDL;
00007 VALUE rb_eDLError;
00008 VALUE rb_eDLTypeError;
00009
00010 ID rbdl_id_cdecl;
00011 ID rbdl_id_stdcall;
00012
00013 VALUE
00014 rb_dl_dlopen(int argc, VALUE argv[], VALUE self)
00015 {
00016 return rb_class_new_instance(argc, argv, rb_cDLHandle);
00017 }
00018
00019
00020
00021
00022
00023
00024
00025 VALUE
00026 rb_dl_malloc(VALUE self, VALUE size)
00027 {
00028 void *ptr;
00029
00030 rb_secure(4);
00031 ptr = (void*)ruby_xmalloc(NUM2INT(size));
00032 return PTR2NUM(ptr);
00033 }
00034
00035
00036
00037
00038
00039
00040
00041
00042 VALUE
00043 rb_dl_realloc(VALUE self, VALUE addr, VALUE size)
00044 {
00045 void *ptr = NUM2PTR(addr);
00046
00047 rb_secure(4);
00048 ptr = (void*)ruby_xrealloc(ptr, NUM2INT(size));
00049 return PTR2NUM(ptr);
00050 }
00051
00052
00053
00054
00055
00056
00057 VALUE
00058 rb_dl_free(VALUE self, VALUE addr)
00059 {
00060 void *ptr = NUM2PTR(addr);
00061
00062 rb_secure(4);
00063 ruby_xfree(ptr);
00064 return Qnil;
00065 }
00066
00067 VALUE
00068 rb_dl_ptr2value(VALUE self, VALUE addr)
00069 {
00070 rb_secure(4);
00071 return (VALUE)NUM2PTR(addr);
00072 }
00073
00074 VALUE
00075 rb_dl_value2ptr(VALUE self, VALUE val)
00076 {
00077 return PTR2NUM((void*)val);
00078 }
00079
00080 static void
00081 rb_dl_init_callbacks(VALUE dl)
00082 {
00083 static const char cb[] = "dl/callback.so";
00084
00085 rb_autoload(dl, rb_intern_const("CdeclCallbackAddrs"), cb);
00086 rb_autoload(dl, rb_intern_const("CdeclCallbackProcs"), cb);
00087 #ifdef FUNC_STDCALL
00088 rb_autoload(dl, rb_intern_const("StdcallCallbackAddrs"), cb);
00089 rb_autoload(dl, rb_intern_const("StdcallCallbackProcs"), cb);
00090 #endif
00091 }
00092
00093 void
00094 Init_dl(void)
00095 {
00096 void Init_dlhandle(void);
00097 void Init_dlcfunc(void);
00098 void Init_dlptr(void);
00099
00100 rbdl_id_cdecl = rb_intern_const("cdecl");
00101 rbdl_id_stdcall = rb_intern_const("stdcall");
00102
00103 rb_mDL = rb_define_module("DL");
00104 rb_eDLError = rb_define_class_under(rb_mDL, "DLError", rb_eStandardError);
00105 rb_eDLTypeError = rb_define_class_under(rb_mDL, "DLTypeError", rb_eDLError);
00106
00107 rb_define_const(rb_mDL, "MAX_CALLBACK", INT2NUM(MAX_CALLBACK));
00108 rb_define_const(rb_mDL, "DLSTACK_SIZE", INT2NUM(DLSTACK_SIZE));
00109
00110 rb_dl_init_callbacks(rb_mDL);
00111
00112 rb_define_const(rb_mDL, "RTLD_GLOBAL", INT2NUM(RTLD_GLOBAL));
00113 rb_define_const(rb_mDL, "RTLD_LAZY", INT2NUM(RTLD_LAZY));
00114 rb_define_const(rb_mDL, "RTLD_NOW", INT2NUM(RTLD_NOW));
00115
00116 rb_define_const(rb_mDL, "TYPE_VOID", INT2NUM(DLTYPE_VOID));
00117 rb_define_const(rb_mDL, "TYPE_VOIDP", INT2NUM(DLTYPE_VOIDP));
00118 rb_define_const(rb_mDL, "TYPE_CHAR", INT2NUM(DLTYPE_CHAR));
00119 rb_define_const(rb_mDL, "TYPE_SHORT", INT2NUM(DLTYPE_SHORT));
00120 rb_define_const(rb_mDL, "TYPE_INT", INT2NUM(DLTYPE_INT));
00121 rb_define_const(rb_mDL, "TYPE_LONG", INT2NUM(DLTYPE_LONG));
00122 #if HAVE_LONG_LONG
00123 rb_define_const(rb_mDL, "TYPE_LONG_LONG", INT2NUM(DLTYPE_LONG_LONG));
00124 #endif
00125 rb_define_const(rb_mDL, "TYPE_FLOAT", INT2NUM(DLTYPE_FLOAT));
00126 rb_define_const(rb_mDL, "TYPE_DOUBLE", INT2NUM(DLTYPE_DOUBLE));
00127
00128 rb_define_const(rb_mDL, "ALIGN_VOIDP", INT2NUM(ALIGN_VOIDP));
00129 rb_define_const(rb_mDL, "ALIGN_CHAR", INT2NUM(ALIGN_CHAR));
00130 rb_define_const(rb_mDL, "ALIGN_SHORT", INT2NUM(ALIGN_SHORT));
00131 rb_define_const(rb_mDL, "ALIGN_INT", INT2NUM(ALIGN_INT));
00132 rb_define_const(rb_mDL, "ALIGN_LONG", INT2NUM(ALIGN_LONG));
00133 #if HAVE_LONG_LONG
00134 rb_define_const(rb_mDL, "ALIGN_LONG_LONG", INT2NUM(ALIGN_LONG_LONG));
00135 #endif
00136 rb_define_const(rb_mDL, "ALIGN_FLOAT", INT2NUM(ALIGN_FLOAT));
00137 rb_define_const(rb_mDL, "ALIGN_DOUBLE",INT2NUM(ALIGN_DOUBLE));
00138
00139 rb_define_const(rb_mDL, "SIZEOF_VOIDP", INT2NUM(sizeof(void*)));
00140 rb_define_const(rb_mDL, "SIZEOF_CHAR", INT2NUM(sizeof(char)));
00141 rb_define_const(rb_mDL, "SIZEOF_SHORT", INT2NUM(sizeof(short)));
00142 rb_define_const(rb_mDL, "SIZEOF_INT", INT2NUM(sizeof(int)));
00143 rb_define_const(rb_mDL, "SIZEOF_LONG", INT2NUM(sizeof(long)));
00144 #if HAVE_LONG_LONG
00145 rb_define_const(rb_mDL, "SIZEOF_LONG_LONG", INT2NUM(sizeof(LONG_LONG)));
00146 #endif
00147 rb_define_const(rb_mDL, "SIZEOF_FLOAT", INT2NUM(sizeof(float)));
00148 rb_define_const(rb_mDL, "SIZEOF_DOUBLE",INT2NUM(sizeof(double)));
00149
00150 rb_define_module_function(rb_mDL, "dlwrap", rb_dl_value2ptr, 1);
00151 rb_define_module_function(rb_mDL, "dlunwrap", rb_dl_ptr2value, 1);
00152
00153 rb_define_module_function(rb_mDL, "dlopen", rb_dl_dlopen, -1);
00154 rb_define_module_function(rb_mDL, "malloc", rb_dl_malloc, 1);
00155 rb_define_module_function(rb_mDL, "realloc", rb_dl_realloc, 2);
00156 rb_define_module_function(rb_mDL, "free", rb_dl_free, 1);
00157
00158 rb_define_const(rb_mDL, "RUBY_FREE", PTR2NUM(ruby_xfree));
00159 rb_define_const(rb_mDL, "BUILD_RUBY_PLATFORM", rb_str_new2(RUBY_PLATFORM));
00160 rb_define_const(rb_mDL, "BUILD_RUBY_VERSION", rb_str_new2(RUBY_VERSION));
00161
00162 Init_dlhandle();
00163 Init_dlcfunc();
00164 Init_dlptr();
00165 }
00166