diff options
Diffstat (limited to 'ruby_1_9_3/ext/dl/dl.c')
-rw-r--r-- | ruby_1_9_3/ext/dl/dl.c | 407 |
1 files changed, 407 insertions, 0 deletions
diff --git a/ruby_1_9_3/ext/dl/dl.c b/ruby_1_9_3/ext/dl/dl.c new file mode 100644 index 0000000000..e0617047ec --- /dev/null +++ b/ruby_1_9_3/ext/dl/dl.c @@ -0,0 +1,407 @@ +/* + * ext/dl/dl.c + * + * doumentation: + * - Vincent Batts (vbatts@hashbangbash.com) + * + */ +#include <ruby/ruby.h> +#include <ruby/io.h> +#include <ctype.h> +#include "dl.h" + +VALUE rb_mDL; +VALUE rb_eDLError; +VALUE rb_eDLTypeError; + +ID rbdl_id_cdecl; +ID rbdl_id_stdcall; + +VALUE +rb_dl_dlopen(int argc, VALUE argv[], VALUE self) +{ + return rb_class_new_instance(argc, argv, rb_cDLHandle); +} + +/* + * call-seq: DL.malloc + * + * Allocate +size+ bytes of memory and return the integer memory address + * for the allocated memory. + */ +VALUE +rb_dl_malloc(VALUE self, VALUE size) +{ + void *ptr; + + rb_secure(4); + ptr = (void*)ruby_xmalloc(NUM2INT(size)); + return PTR2NUM(ptr); +} + +/* + * call-seq: DL.realloc(addr, size) + * + * Change the size of the memory allocated at the memory location +addr+ to + * +size+ bytes. Returns the memory address of the reallocated memory, which + * may be different than the address passed in. + */ +VALUE +rb_dl_realloc(VALUE self, VALUE addr, VALUE size) +{ + void *ptr = NUM2PTR(addr); + + rb_secure(4); + ptr = (void*)ruby_xrealloc(ptr, NUM2INT(size)); + return PTR2NUM(ptr); +} + +/* + * call-seq: DL.free(addr) + * + * Free the memory at address +addr+ + */ +VALUE +rb_dl_free(VALUE self, VALUE addr) +{ + void *ptr = NUM2PTR(addr); + + rb_secure(4); + ruby_xfree(ptr); + return Qnil; +} + +VALUE +rb_dl_ptr2value(VALUE self, VALUE addr) +{ + rb_secure(4); + return (VALUE)NUM2PTR(addr); +} + +VALUE +rb_dl_value2ptr(VALUE self, VALUE val) +{ + return PTR2NUM((void*)val); +} + +static void +rb_dl_init_callbacks(VALUE dl) +{ + static const char cb[] = "dl/callback.so"; + + rb_autoload(dl, rb_intern_const("CdeclCallbackAddrs"), cb); + rb_autoload(dl, rb_intern_const("CdeclCallbackProcs"), cb); +#ifdef FUNC_STDCALL + rb_autoload(dl, rb_intern_const("StdcallCallbackAddrs"), cb); + rb_autoload(dl, rb_intern_const("StdcallCallbackProcs"), cb); +#endif +} + +void +Init_dl(void) +{ + void Init_dlhandle(void); + void Init_dlcfunc(void); + void Init_dlptr(void); + + rbdl_id_cdecl = rb_intern_const("cdecl"); + rbdl_id_stdcall = rb_intern_const("stdcall"); + + /* Document-module: DL + * + * A bridge to the dlopen() or dynamic library linker function. + * + * == Example + * + * bash $> cat > sum.c <<EOF + * double sum(double *arry, int len) + * { + * double ret = 0; + * int i; + * for(i = 0; i < len; i++){ + * ret = ret + arry[i]; + * } + * return ret; + * } + * + * double split(double num) + * { + * double ret = 0; + * ret = num / 2; + * return ret; + * } + * EOF + * bash $> gcc -o libsum.so -shared sum.c + * bash $> cat > sum.rb <<EOF + * require 'dl' + * require 'dl/import' + * + * module LibSum + * extend DL::Importer + * dlload './libsum.so' + * extern 'double sum(double*, int)' + * extern 'double split(double)' + * end + * + * a = [2.0, 3.0, 4.0] + * + * sum = LibSum.sum(a.pack("d*"), a.count) + * p LibSum.split(sum) + * EOF + * bash $> ruby sum.rb + * 4.5 + * + * WIN! :-) + */ + rb_mDL = rb_define_module("DL"); + + /* + * Document-class: DL::DLError + * + * standard dynamic load exception + */ + rb_eDLError = rb_define_class_under(rb_mDL, "DLError", rb_eStandardError); + + /* + * Document-class: DL::DLTypeError + * + * dynamic load incorrect type exception + */ + rb_eDLTypeError = rb_define_class_under(rb_mDL, "DLTypeError", rb_eDLError); + + /* Document-const: MAX_CALLBACK + * + * Maximum number of callbacks + */ + rb_define_const(rb_mDL, "MAX_CALLBACK", INT2NUM(MAX_CALLBACK)); + + /* Document-const: DLSTACK_SIZE + * + * Dynamic linker stack size + */ + rb_define_const(rb_mDL, "DLSTACK_SIZE", INT2NUM(DLSTACK_SIZE)); + + rb_dl_init_callbacks(rb_mDL); + + /* Document-const: RTLD_GLOBAL + * + * rtld DL::Handle flag. + * + * The symbols defined by this library will be made available for symbol + * resolution of subsequently loaded libraries. + */ + rb_define_const(rb_mDL, "RTLD_GLOBAL", INT2NUM(RTLD_GLOBAL)); + + /* Document-const: RTLD_LAZY + * + * rtld DL::Handle flag. + * + * Perform lazy binding. Only resolve symbols as the code that references + * them is executed. If the symbol is never referenced, then it is never + * resolved. (Lazy binding is only performed for function references; + * references to variables are always immediately bound when the library + * is loaded.) + */ + rb_define_const(rb_mDL, "RTLD_LAZY", INT2NUM(RTLD_LAZY)); + + /* Document-const: RTLD_NOW + * + * rtld DL::Handle flag. + * + * If this value is specified or the environment variable LD_BIND_NOW is + * set to a nonempty string, all undefined symbols in the library are + * resolved before dlopen() returns. If this cannot be done an error is + * returned. + */ + rb_define_const(rb_mDL, "RTLD_NOW", INT2NUM(RTLD_NOW)); + + /* Document-const: TYPE_VOID + * + * DL::CFunc type - void + */ + rb_define_const(rb_mDL, "TYPE_VOID", INT2NUM(DLTYPE_VOID)); + + /* Document-const: TYPE_VOIDP + * + * DL::CFunc type - void* + */ + rb_define_const(rb_mDL, "TYPE_VOIDP", INT2NUM(DLTYPE_VOIDP)); + + /* Document-const: TYPE_CHAR + * + * DL::CFunc type - char + */ + rb_define_const(rb_mDL, "TYPE_CHAR", INT2NUM(DLTYPE_CHAR)); + + /* Document-const: TYPE_SHORT + * + * DL::CFunc type - short + */ + rb_define_const(rb_mDL, "TYPE_SHORT", INT2NUM(DLTYPE_SHORT)); + + /* Document-const: TYPE_INT + * + * DL::CFunc type - int + */ + rb_define_const(rb_mDL, "TYPE_INT", INT2NUM(DLTYPE_INT)); + + /* Document-const: TYPE_LONG + * + * DL::CFunc type - long + */ + rb_define_const(rb_mDL, "TYPE_LONG", INT2NUM(DLTYPE_LONG)); + +#if HAVE_LONG_LONG + /* Document-const: TYPE_LONG_LONG + * + * DL::CFunc type - long long + */ + rb_define_const(rb_mDL, "TYPE_LONG_LONG", INT2NUM(DLTYPE_LONG_LONG)); +#endif + + /* Document-const: TYPE_FLOAT + * + * DL::CFunc type - float + */ + rb_define_const(rb_mDL, "TYPE_FLOAT", INT2NUM(DLTYPE_FLOAT)); + + /* Document-const: TYPE_DOUBLE + * + * DL::CFunc type - double + */ + rb_define_const(rb_mDL, "TYPE_DOUBLE", INT2NUM(DLTYPE_DOUBLE)); + + /* Document-const: ALIGN_VOIDP + * + * The Offset of a struct void* and a void* + */ + rb_define_const(rb_mDL, "ALIGN_VOIDP", INT2NUM(ALIGN_VOIDP)); + + /* Document-const: ALIGN_CHAR + * + * The Offset of a struct char and a char + */ + rb_define_const(rb_mDL, "ALIGN_CHAR", INT2NUM(ALIGN_CHAR)); + + /* Document-const: ALIGN_SHORT + * + * The Offset of a struct short and a short + */ + rb_define_const(rb_mDL, "ALIGN_SHORT", INT2NUM(ALIGN_SHORT)); + + /* Document-const: ALIGN_INT + * + * The Offset of a struct int and a int + */ + rb_define_const(rb_mDL, "ALIGN_INT", INT2NUM(ALIGN_INT)); + + /* Document-const: ALIGN_LONG + * + * The Offset of a struct long and a long + */ + rb_define_const(rb_mDL, "ALIGN_LONG", INT2NUM(ALIGN_LONG)); + +#if HAVE_LONG_LONG + /* Document-const: ALIGN_LONG_LONG + * + * The Offset of a struct long long and a long long + */ + rb_define_const(rb_mDL, "ALIGN_LONG_LONG", INT2NUM(ALIGN_LONG_LONG)); +#endif + + /* Document-const: ALIGN_FLOAT + * + * The Offset of a struct float and a float + */ + rb_define_const(rb_mDL, "ALIGN_FLOAT", INT2NUM(ALIGN_FLOAT)); + + /* Document-const: ALIGN_DOUBLE + * + * The Offset of a struct double and a double + */ + rb_define_const(rb_mDL, "ALIGN_DOUBLE",INT2NUM(ALIGN_DOUBLE)); + + /* Document-const: SIZEOF_VOIDP + * + * OS Dependent - sizeof(void*) + */ + rb_define_const(rb_mDL, "SIZEOF_VOIDP", INT2NUM(sizeof(void*))); + + /* Document-const: SIZEOF_CHAR + * + * OS Dependent - sizeof(char) + */ + rb_define_const(rb_mDL, "SIZEOF_CHAR", INT2NUM(sizeof(char))); + + /* Document-const: SIZEOF_SHORT + * + * OS Dependent - sizeof(short) + */ + rb_define_const(rb_mDL, "SIZEOF_SHORT", INT2NUM(sizeof(short))); + + /* Document-const: SIZEOF_INT + * + * OS Dependent - sizeof(int) + */ + rb_define_const(rb_mDL, "SIZEOF_INT", INT2NUM(sizeof(int))); + + /* Document-const: SIZEOF_LONG + * + * OS Dependent - sizeof(long) + */ + rb_define_const(rb_mDL, "SIZEOF_LONG", INT2NUM(sizeof(long))); + +#if HAVE_LONG_LONG + /* Document-const: SIZEOF_LONG_LONG + * + * OS Dependent - sizeof(long long) + */ + rb_define_const(rb_mDL, "SIZEOF_LONG_LONG", INT2NUM(sizeof(LONG_LONG))); +#endif + + /* Document-const: SIZEOF_FLOAT + * + * OS Dependent - sizeof(float) + */ + rb_define_const(rb_mDL, "SIZEOF_FLOAT", INT2NUM(sizeof(float))); + + /* Document-const: SIZEOF_DOUBLE + * + * OS Dependent - sizeof(double) + */ + rb_define_const(rb_mDL, "SIZEOF_DOUBLE",INT2NUM(sizeof(double))); + + rb_define_module_function(rb_mDL, "dlwrap", rb_dl_value2ptr, 1); + rb_define_module_function(rb_mDL, "dlunwrap", rb_dl_ptr2value, 1); + + rb_define_module_function(rb_mDL, "dlopen", rb_dl_dlopen, -1); + rb_define_module_function(rb_mDL, "malloc", rb_dl_malloc, 1); + rb_define_module_function(rb_mDL, "realloc", rb_dl_realloc, 2); + rb_define_module_function(rb_mDL, "free", rb_dl_free, 1); + + /* Document-const: RUBY_FREE + * + * Address of the ruby_xfree() function + */ + rb_define_const(rb_mDL, "RUBY_FREE", PTR2NUM(ruby_xfree)); + + /* Document-const: BUILD_RUBY_PLATFORM + * + * Platform built against (i.e. "x86_64-linux", etc.) + * + * See also RUBY_PLATFORM + */ + rb_define_const(rb_mDL, "BUILD_RUBY_PLATFORM", rb_str_new2(RUBY_PLATFORM)); + + /* Document-const: BUILD_RUBY_VERSION + * + * Ruby Version built. (i.e. "1.9.3") + * + * See also RUBY_VERSION + */ + rb_define_const(rb_mDL, "BUILD_RUBY_VERSION", rb_str_new2(RUBY_VERSION)); + + Init_dlhandle(); + Init_dlcfunc(); + Init_dlptr(); +} |