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! :-)
- MODULE DL::BasicTypes
- MODULE DL::CParser
- MODULE DL::CStructBuilder
- MODULE DL::Fiddle
- MODULE DL::Importer
- MODULE DL::PackInfo
- MODULE DL::ValueUtil
- MODULE DL::Win32Types
- CLASS DL::CFunc
- CLASS DL::CPtr
- CLASS DL::CStruct
- CLASS DL::CStructEntity
- CLASS DL::CUnion
- CLASS DL::CUnionEntity
- CLASS DL::CarriedFunction
- CLASS DL::CompositeHandler
- CLASS DL::DLError
- CLASS DL::DLTypeError
- CLASS DL::Function
- CLASS DL::Handle
- CLASS DL::Packer
- CLASS DL::Stack
- CLASS DL::TempFunction
- D
- F
- M
- R
- S
NULL | = | Document-const |
A NULL pointer |
||
MAX_CALLBACK | = | Document-const |
Maximum number of callbacks |
||
DLSTACK_SIZE | = | Document-const |
Dynamic linker stack size |
||
RTLD_GLOBAL | = | Document-const |
rtld DL::Handle flag. The symbols defined by this library will be made available for symbol resolution of subsequently loaded libraries. |
||
RTLD_LAZY | = | Document-const |
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.) |
||
RTLD_NOW | = | Document-const |
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. |
||
TYPE_VOID | = | Document-const |
DL::CFunc type - void |
||
TYPE_VOIDP | = | Document-const |
DL::CFunc type - void* |
||
TYPE_CHAR | = | Document-const |
DL::CFunc type - char |
||
TYPE_SHORT | = | Document-const |
DL::CFunc type - short |
||
TYPE_INT | = | Document-const |
DL::CFunc type - int |
||
TYPE_LONG | = | Document-const |
DL::CFunc type - long |
||
TYPE_LONG_LONG | = | Document-const |
DL::CFunc type - long long |
||
TYPE_FLOAT | = | Document-const |
DL::CFunc type - float |
||
TYPE_DOUBLE | = | Document-const |
DL::CFunc type - double |
||
ALIGN_VOIDP | = | Document-const |
The Offset of a struct void* and a void* |
||
ALIGN_CHAR | = | Document-const |
The Offset of a struct char and a char |
||
ALIGN_SHORT | = | Document-const |
The Offset of a struct short and a short |
||
ALIGN_INT | = | Document-const |
The Offset of a struct int and a int |
||
ALIGN_LONG | = | Document-const |
The Offset of a struct long and a long |
||
ALIGN_LONG_LONG | = | Document-const |
The Offset of a struct long long and a long long |
||
ALIGN_FLOAT | = | Document-const |
The Offset of a struct float and a float |
||
ALIGN_DOUBLE | = | Document-const |
The Offset of a struct double and a double |
||
SIZEOF_VOIDP | = | Document-const |
OS Dependent - sizeof(void*) |
||
SIZEOF_CHAR | = | Document-const |
OS Dependent - sizeof(char) |
||
SIZEOF_SHORT | = | Document-const |
OS Dependent - sizeof(short) |
||
SIZEOF_INT | = | Document-const |
OS Dependent - sizeof(int) |
||
SIZEOF_LONG | = | Document-const |
OS Dependent - sizeof(long) |
||
SIZEOF_LONG_LONG | = | Document-const |
OS Dependent - sizeof(long long) |
||
SIZEOF_FLOAT | = | Document-const |
OS Dependent - sizeof(float) |
||
SIZEOF_DOUBLE | = | Document-const |
OS Dependent - sizeof(double) |
||
RUBY_FREE | = | Document-const |
Address of the ruby_xfree() function |
||
BUILD_RUBY_PLATFORM | = | Document-const |
Platform built against (i.e. "x86_64-linux", etc.) See also RUBY_PLATFORM |
||
BUILD_RUBY_VERSION | = | Document-const |
Ruby Version built. (i.e. "1.9.3") See also RUBY_VERSION |
||
SEM | = | Mutex.new # :nodoc: |
The mutual exclusion (Mutex) semaphore for the DL module |
||
CdeclCallbackProcs | = | {} |
A Hash of callback Procs Uses Fiddle |
||
CdeclCallbackAddrs | = | {} |
A Hash of the addresses of callback Proc Uses Fiddle |
||
StdcallCallbackProcs | = | {} |
A Hash of Stdcall callback Procs Uses Fiddle on win32 |
||
StdcallCallbackAddrs | = | {} |
A Hash of the addresses of Stdcall callback Procs Uses Fiddle on win32 |
Source: show
VALUE rb_dl_dlopen(int argc, VALUE argv[], VALUE self) { return rb_class_new_instance(argc, argv, rb_cDLHandle); }
Source: show
VALUE rb_dl_ptr2value(VALUE self, VALUE addr) { rb_secure(4); return (VALUE)NUM2PTR(addr); }
Source: show
VALUE rb_dl_value2ptr(VALUE self, VALUE val) { return PTR2NUM((void*)val); }
Free the memory at address addr
Source: show
VALUE rb_dl_free(VALUE self, VALUE addr) { void *ptr = NUM2PTR(addr); rb_secure(4); ruby_xfree(ptr); return Qnil; }
Allocate size
bytes of memory and return the integer memory
address for the allocated memory.
Source: show
VALUE rb_dl_malloc(VALUE self, VALUE size) { void *ptr; rb_secure(4); ptr = (void*)ruby_xmalloc(NUM2INT(size)); return PTR2NUM(ptr); }
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.
Source: show
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); }
# File ../ruby/ext/dl/lib/dl/callback.rb, line 70 def remove_callback_internal(proc_entry, addr_entry, addr, ctype = nil) if DL.fiddle? addr = addr.to_i return false unless proc_entry.key?(addr) proc_entry.delete(addr) true else index = nil if( ctype ) addr_entry[ctype].each_with_index{|xaddr, idx| if( xaddr == addr ) index = idx end } else addr_entry.each{|ty,entry| entry.each_with_index{|xaddr, idx| if( xaddr == addr ) index = idx end } } end if( index and proc_entry[ctype][index] ) proc_entry[ctype][index] = nil return true else return false end end end
# File ../ruby/ext/dl/lib/dl/callback.rb, line 30 def set_callback_internal(proc_entry, addr_entry, argc, ty, abi = nil, &cbp) if( argc < 0 ) raise(ArgumentError, "arity should not be less than 0.") end addr = nil if DL.fiddle? abi ||= Fiddle::Function::DEFAULT closure = Fiddle::Closure::BlockCaller.new(ty, [TYPE_VOIDP] * argc, abi, &cbp) proc_entry[closure.to_i] = closure addr = closure.to_i else SEM.synchronize{ ary = proc_entry[ty] (0...MAX_CALLBACK).each{|n| idx = (n * DLSTACK_SIZE) + argc if( ary[idx].nil? ) ary[idx] = cbp addr = addr_entry[ty][idx] break end } } end addr end
# File ../ruby/ext/dl/lib/dl/callback.rb, line 62 def set_stdcall_callback(ty, argc, &cbp) if DL.fiddle? set_callback_internal(StdcallCallbackProcs, StdcallCallbackAddrs, argc, ty, Fiddle::Function::STDCALL, &cbp) else set_callback_internal(StdcallCallbackProcs, StdcallCallbackAddrs, argc, ty, &cbp) end end