ext/fiddle/fiddle.c

Go to the documentation of this file.
00001 #include <fiddle.h>
00002 
00003 VALUE mFiddle;
00004 VALUE rb_eFiddleError;
00005 
00006 #ifndef TYPE_SSIZE_T
00007 # if SIZEOF_SIZE_T == SIZEOF_INT
00008 #   define TYPE_SSIZE_T TYPE_INT
00009 # elif SIZEOF_SIZE_T == SIZEOF_LONG
00010 #   define TYPE_SSIZE_T TYPE_LONG
00011 # elif defined HAVE_LONG_LONG && SIZEOF_SIZE_T == SIZEOF_LONG_LONG
00012 #   define TYPE_SSIZE_T TYPE_LONG_LONG
00013 # endif
00014 #endif
00015 #define TYPE_SIZE_T (-1*SIGNEDNESS_OF_SIZE_T*TYPE_SSIZE_T)
00016 
00017 #ifndef TYPE_PTRDIFF_T
00018 # if SIZEOF_PTRDIFF_T == SIZEOF_INT
00019 #   define TYPE_PTRDIFF_T TYPE_INT
00020 # elif SIZEOF_PTRDIFF_T == SIZEOF_LONG
00021 #   define TYPE_PTRDIFF_T TYPE_LONG
00022 # elif defined HAVE_LONG_LONG && SIZEOF_PTRDIFF_T == SIZEOF_LONG_LONG
00023 #   define TYPE_PTRDIFF_T TYPE_LONG_LONG
00024 # endif
00025 #endif
00026 
00027 #ifndef TYPE_INTPTR_T
00028 # if SIZEOF_INTPTR_T == SIZEOF_INT
00029 #   define TYPE_INTPTR_T TYPE_INT
00030 # elif SIZEOF_INTPTR_T == SIZEOF_LONG
00031 #   define TYPE_INTPTR_T TYPE_LONG
00032 # elif defined HAVE_LONG_LONG && SIZEOF_INTPTR_T == SIZEOF_LONG_LONG
00033 #   define TYPE_INTPTR_T TYPE_LONG_LONG
00034 # endif
00035 #endif
00036 #define TYPE_UINTPTR_T (-TYPE_INTPTR_T)
00037 
00038 void Init_fiddle_pointer(void);
00039 
00040 /*
00041  * call-seq: Fiddle.malloc(size)
00042  *
00043  * Allocate +size+ bytes of memory and return the integer memory address
00044  * for the allocated memory.
00045  */
00046 static VALUE
00047 rb_fiddle_malloc(VALUE self, VALUE size)
00048 {
00049     void *ptr;
00050 
00051     ptr = (void*)ruby_xmalloc(NUM2INT(size));
00052     return PTR2NUM(ptr);
00053 }
00054 
00055 /*
00056  * call-seq: Fiddle.realloc(addr, size)
00057  *
00058  * Change the size of the memory allocated at the memory location +addr+ to
00059  * +size+ bytes.  Returns the memory address of the reallocated memory, which
00060  * may be different than the address passed in.
00061  */
00062 static VALUE
00063 rb_fiddle_realloc(VALUE self, VALUE addr, VALUE size)
00064 {
00065     void *ptr = NUM2PTR(addr);
00066 
00067     ptr = (void*)ruby_xrealloc(ptr, NUM2INT(size));
00068     return PTR2NUM(ptr);
00069 }
00070 
00071 /*
00072  * call-seq: Fiddle.free(addr)
00073  *
00074  * Free the memory at address +addr+
00075  */
00076 VALUE
00077 rb_fiddle_free(VALUE self, VALUE addr)
00078 {
00079     void *ptr = NUM2PTR(addr);
00080 
00081     ruby_xfree(ptr);
00082     return Qnil;
00083 }
00084 
00085 /*
00086  * call-seq: Fiddle.dlunwrap(addr)
00087  *
00088  * Returns the hexadecimal representation of a memory pointer address +addr+
00089  *
00090  * Example:
00091  *
00092  *   lib = Fiddle.dlopen('/lib64/libc-2.15.so')
00093  *   => #<Fiddle::Handle:0x00000001342460>
00094  *
00095  *   lib['strcpy'].to_s(16)
00096  *   => "7f59de6dd240"
00097  *
00098  *   Fiddle.dlunwrap(Fiddle.dlwrap(lib['strcpy'].to_s(16)))
00099  *   => "7f59de6dd240"
00100  */
00101 VALUE
00102 rb_fiddle_ptr2value(VALUE self, VALUE addr)
00103 {
00104     return (VALUE)NUM2PTR(addr);
00105 }
00106 
00107 /*
00108  * call-seq: Fiddle.dlwrap(val)
00109  *
00110  * Returns a memory pointer of a function's hexadecimal address location +val+
00111  *
00112  * Example:
00113  *
00114  *   lib = Fiddle.dlopen('/lib64/libc-2.15.so')
00115  *   => #<Fiddle::Handle:0x00000001342460>
00116  *
00117  *   Fiddle.dlwrap(lib['strcpy'].to_s(16))
00118  *   => 25522520
00119  */
00120 static VALUE
00121 rb_fiddle_value2ptr(VALUE self, VALUE val)
00122 {
00123     return PTR2NUM((void*)val);
00124 }
00125 
00126 void Init_fiddle_handle(void);
00127 
00128 void
00129 Init_fiddle(void)
00130 {
00131     /*
00132      * Document-module: Fiddle
00133      *
00134      * A libffi wrapper for Ruby.
00135      *
00136      * == Description
00137      *
00138      * Fiddle is an extension to translate a foreign function interface (FFI)
00139      * with ruby.
00140      *
00141      * It wraps {libffi}[http://sourceware.org/libffi/], a popular C library
00142      * which provides a portable interface that allows code written in one
00143      * language to call code written in another language.
00144      *
00145      * == Example
00146      *
00147      * Here we will use Fiddle::Function to wrap {floor(3) from
00148      * libm}[http://linux.die.net/man/3/floor]
00149      *
00150      *      require 'fiddle'
00151      *
00152      *      libm = Fiddle.dlopen('/lib/libm.so.6')
00153      *
00154      *      floor = Fiddle::Function.new(
00155      *        libm['floor'],
00156      *        [Fiddle::TYPE_DOUBLE],
00157      *        Fiddle::TYPE_DOUBLE
00158      *      )
00159      *
00160      *      puts floor.call(3.14159) #=> 3.0
00161      *
00162      *
00163      */
00164     mFiddle = rb_define_module("Fiddle");
00165 
00166     /*
00167      * Document-class: Fiddle::DLError
00168      *
00169      * standard dynamic load exception
00170      */
00171     rb_eFiddleError = rb_define_class_under(mFiddle, "DLError", rb_eStandardError);
00172 
00173     /* Document-const: TYPE_VOID
00174      *
00175      * C type - void
00176      */
00177     rb_define_const(mFiddle, "TYPE_VOID",      INT2NUM(TYPE_VOID));
00178 
00179     /* Document-const: TYPE_VOIDP
00180      *
00181      * C type - void*
00182      */
00183     rb_define_const(mFiddle, "TYPE_VOIDP",     INT2NUM(TYPE_VOIDP));
00184 
00185     /* Document-const: TYPE_CHAR
00186      *
00187      * C type - char
00188      */
00189     rb_define_const(mFiddle, "TYPE_CHAR",      INT2NUM(TYPE_CHAR));
00190 
00191     /* Document-const: TYPE_SHORT
00192      *
00193      * C type - short
00194      */
00195     rb_define_const(mFiddle, "TYPE_SHORT",     INT2NUM(TYPE_SHORT));
00196 
00197     /* Document-const: TYPE_INT
00198      *
00199      * C type - int
00200      */
00201     rb_define_const(mFiddle, "TYPE_INT",       INT2NUM(TYPE_INT));
00202 
00203     /* Document-const: TYPE_LONG
00204      *
00205      * C type - long
00206      */
00207     rb_define_const(mFiddle, "TYPE_LONG",      INT2NUM(TYPE_LONG));
00208 
00209 #if HAVE_LONG_LONG
00210     /* Document-const: TYPE_LONG_LONG
00211      *
00212      * C type - long long
00213      */
00214     rb_define_const(mFiddle, "TYPE_LONG_LONG", INT2NUM(TYPE_LONG_LONG));
00215 #endif
00216 
00217     /* Document-const: TYPE_FLOAT
00218      *
00219      * C type - float
00220      */
00221     rb_define_const(mFiddle, "TYPE_FLOAT",     INT2NUM(TYPE_FLOAT));
00222 
00223     /* Document-const: TYPE_DOUBLE
00224      *
00225      * C type - double
00226      */
00227     rb_define_const(mFiddle, "TYPE_DOUBLE",    INT2NUM(TYPE_DOUBLE));
00228 
00229     /* Document-const: TYPE_SIZE_T
00230      *
00231      * C type - size_t
00232      */
00233     rb_define_const(mFiddle, "TYPE_SIZE_T",   INT2NUM(TYPE_SIZE_T));
00234 
00235     /* Document-const: TYPE_SSIZE_T
00236      *
00237      * C type - ssize_t
00238      */
00239     rb_define_const(mFiddle, "TYPE_SSIZE_T",   INT2NUM(TYPE_SSIZE_T));
00240 
00241     /* Document-const: TYPE_PTRDIFF_T
00242      *
00243      * C type - ptrdiff_t
00244      */
00245     rb_define_const(mFiddle, "TYPE_PTRDIFF_T", INT2NUM(TYPE_PTRDIFF_T));
00246 
00247     /* Document-const: TYPE_INTPTR_T
00248      *
00249      * C type - intptr_t
00250      */
00251     rb_define_const(mFiddle, "TYPE_INTPTR_T",  INT2NUM(TYPE_INTPTR_T));
00252 
00253     /* Document-const: TYPE_UINTPTR_T
00254      *
00255      * C type - uintptr_t
00256      */
00257     rb_define_const(mFiddle, "TYPE_UINTPTR_T",  INT2NUM(TYPE_UINTPTR_T));
00258 
00259     /* Document-const: ALIGN_VOIDP
00260      *
00261      * The alignment size of a void*
00262      */
00263     rb_define_const(mFiddle, "ALIGN_VOIDP", INT2NUM(ALIGN_VOIDP));
00264 
00265     /* Document-const: ALIGN_CHAR
00266      *
00267      * The alignment size of a char
00268      */
00269     rb_define_const(mFiddle, "ALIGN_CHAR",  INT2NUM(ALIGN_CHAR));
00270 
00271     /* Document-const: ALIGN_SHORT
00272      *
00273      * The alignment size of a short
00274      */
00275     rb_define_const(mFiddle, "ALIGN_SHORT", INT2NUM(ALIGN_SHORT));
00276 
00277     /* Document-const: ALIGN_INT
00278      *
00279      * The alignment size of an int
00280      */
00281     rb_define_const(mFiddle, "ALIGN_INT",   INT2NUM(ALIGN_INT));
00282 
00283     /* Document-const: ALIGN_LONG
00284      *
00285      * The alignment size of a long
00286      */
00287     rb_define_const(mFiddle, "ALIGN_LONG",  INT2NUM(ALIGN_LONG));
00288 
00289 #if HAVE_LONG_LONG
00290     /* Document-const: ALIGN_LONG_LONG
00291      *
00292      * The alignment size of a long long
00293      */
00294     rb_define_const(mFiddle, "ALIGN_LONG_LONG",  INT2NUM(ALIGN_LONG_LONG));
00295 #endif
00296 
00297     /* Document-const: ALIGN_FLOAT
00298      *
00299      * The alignment size of a float
00300      */
00301     rb_define_const(mFiddle, "ALIGN_FLOAT", INT2NUM(ALIGN_FLOAT));
00302 
00303     /* Document-const: ALIGN_DOUBLE
00304      *
00305      * The alignment size of a double
00306      */
00307     rb_define_const(mFiddle, "ALIGN_DOUBLE",INT2NUM(ALIGN_DOUBLE));
00308 
00309     /* Document-const: ALIGN_SIZE_T
00310      *
00311      * The alignment size of a size_t
00312      */
00313     rb_define_const(mFiddle, "ALIGN_SIZE_T", INT2NUM(ALIGN_OF(size_t)));
00314 
00315     /* Document-const: ALIGN_SSIZE_T
00316      *
00317      * The alignment size of a ssize_t
00318      */
00319     rb_define_const(mFiddle, "ALIGN_SSIZE_T", INT2NUM(ALIGN_OF(size_t))); /* same as size_t */
00320 
00321     /* Document-const: ALIGN_PTRDIFF_T
00322      *
00323      * The alignment size of a ptrdiff_t
00324      */
00325     rb_define_const(mFiddle, "ALIGN_PTRDIFF_T", INT2NUM(ALIGN_OF(ptrdiff_t)));
00326 
00327     /* Document-const: ALIGN_INTPTR_T
00328      *
00329      * The alignment size of a intptr_t
00330      */
00331     rb_define_const(mFiddle, "ALIGN_INTPTR_T", INT2NUM(ALIGN_OF(intptr_t)));
00332 
00333     /* Document-const: ALIGN_UINTPTR_T
00334      *
00335      * The alignment size of a uintptr_t
00336      */
00337     rb_define_const(mFiddle, "ALIGN_UINTPTR_T", INT2NUM(ALIGN_OF(uintptr_t)));
00338 
00339     /* Document-const: WINDOWS
00340      *
00341      * Returns a boolean regarding whether the host is WIN32
00342      */
00343 #if defined(_WIN32)
00344     rb_define_const(mFiddle, "WINDOWS", Qtrue);
00345 #else
00346     rb_define_const(mFiddle, "WINDOWS", Qfalse);
00347 #endif
00348 
00349     /* Document-const: SIZEOF_VOIDP
00350      *
00351      * size of a void*
00352      */
00353     rb_define_const(mFiddle, "SIZEOF_VOIDP", INT2NUM(sizeof(void*)));
00354 
00355     /* Document-const: SIZEOF_CHAR
00356      *
00357      * size of a char
00358      */
00359     rb_define_const(mFiddle, "SIZEOF_CHAR",  INT2NUM(sizeof(char)));
00360 
00361     /* Document-const: SIZEOF_SHORT
00362      *
00363      * size of a short
00364      */
00365     rb_define_const(mFiddle, "SIZEOF_SHORT", INT2NUM(sizeof(short)));
00366 
00367     /* Document-const: SIZEOF_INT
00368      *
00369      * size of an int
00370      */
00371     rb_define_const(mFiddle, "SIZEOF_INT",   INT2NUM(sizeof(int)));
00372 
00373     /* Document-const: SIZEOF_LONG
00374      *
00375      * size of a long
00376      */
00377     rb_define_const(mFiddle, "SIZEOF_LONG",  INT2NUM(sizeof(long)));
00378 
00379 #if HAVE_LONG_LONG
00380     /* Document-const: SIZEOF_LONG_LONG
00381      *
00382      * size of a long long
00383      */
00384     rb_define_const(mFiddle, "SIZEOF_LONG_LONG",  INT2NUM(sizeof(LONG_LONG)));
00385 #endif
00386 
00387     /* Document-const: SIZEOF_FLOAT
00388      *
00389      * size of a float
00390      */
00391     rb_define_const(mFiddle, "SIZEOF_FLOAT", INT2NUM(sizeof(float)));
00392 
00393     /* Document-const: SIZEOF_DOUBLE
00394      *
00395      * size of a double
00396      */
00397     rb_define_const(mFiddle, "SIZEOF_DOUBLE",INT2NUM(sizeof(double)));
00398 
00399     /* Document-const: SIZEOF_SIZE_T
00400      *
00401      * size of a size_t
00402      */
00403     rb_define_const(mFiddle, "SIZEOF_SIZE_T",  INT2NUM(sizeof(size_t)));
00404 
00405     /* Document-const: SIZEOF_SSIZE_T
00406      *
00407      * size of a ssize_t
00408      */
00409     rb_define_const(mFiddle, "SIZEOF_SSIZE_T",  INT2NUM(sizeof(size_t))); /* same as size_t */
00410 
00411     /* Document-const: SIZEOF_PTRDIFF_T
00412      *
00413      * size of a ptrdiff_t
00414      */
00415     rb_define_const(mFiddle, "SIZEOF_PTRDIFF_T",  INT2NUM(sizeof(ptrdiff_t)));
00416 
00417     /* Document-const: SIZEOF_INTPTR_T
00418      *
00419      * size of a intptr_t
00420      */
00421     rb_define_const(mFiddle, "SIZEOF_INTPTR_T",  INT2NUM(sizeof(intptr_t)));
00422 
00423     /* Document-const: SIZEOF_UINTPTR_T
00424      *
00425      * size of a uintptr_t
00426      */
00427     rb_define_const(mFiddle, "SIZEOF_UINTPTR_T",  INT2NUM(sizeof(uintptr_t)));
00428 
00429     /* Document-const: RUBY_FREE
00430      *
00431      * Address of the ruby_xfree() function
00432      */
00433     rb_define_const(mFiddle, "RUBY_FREE", PTR2NUM(ruby_xfree));
00434 
00435     /* Document-const: BUILD_RUBY_PLATFORM
00436      *
00437      * Platform built against (i.e. "x86_64-linux", etc.)
00438      *
00439      * See also RUBY_PLATFORM
00440      */
00441     rb_define_const(mFiddle, "BUILD_RUBY_PLATFORM", rb_str_new2(RUBY_PLATFORM));
00442 
00443     rb_define_module_function(mFiddle, "dlwrap", rb_fiddle_value2ptr, 1);
00444     rb_define_module_function(mFiddle, "dlunwrap", rb_fiddle_ptr2value, 1);
00445     rb_define_module_function(mFiddle, "malloc", rb_fiddle_malloc, 1);
00446     rb_define_module_function(mFiddle, "realloc", rb_fiddle_realloc, 2);
00447     rb_define_module_function(mFiddle, "free", rb_fiddle_free, 1);
00448 
00449     Init_fiddle_function();
00450     Init_fiddle_closure();
00451     Init_fiddle_handle();
00452     Init_fiddle_pointer();
00453 }
00454 /* vim: set noet sws=4 sw=4: */
00455 

Generated on 19 Jul 2016 for Ruby by  doxygen 1.4.7