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