Module: DL
- Defined in:
- dl.c,
lib/dl.rb,
lib/dl/pack.rb,
lib/dl/func.rb,
lib/dl/stack.rb,
lib/dl/value.rb,
lib/dl/types.rb,
lib/dl/struct.rb,
lib/dl/import.rb,
lib/dl/cparser.rb,
lib/dl/callback.rb
Overview
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! :-)
Defined Under Namespace
Modules: BasicTypes, CParser, CStructBuilder, Importer, PackInfo, ValueUtil, Win32Types Classes: CFunc, CPtr, CStruct, CStructEntity, CUnion, CUnionEntity, CarriedFunction, CompositeHandler, DLError, DLTypeError, Function, Handle, Packer, Stack, TempFunction
Constant Summary collapse
- MAX_CALLBACK =
Maximum number of callbacks
INT2NUM(MAX_CALLBACK)
- DLSTACK_SIZE =
Dynamic linker stack size
INT2NUM(DLSTACK_SIZE)
- RTLD_GLOBAL =
:Handle flag.
The symbols defined by this library will be made available for symbol resolution of subsequently loaded libraries.
rtld DL
- RTLD_LAZY =
: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 DL
- RTLD_NOW =
: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.
rtld DL
- TYPE_VOID =
:CFunc type - void
DL
- TYPE_VOIDP =
:CFunc type - void*
DL
- TYPE_CHAR =
:CFunc type - char
DL
- TYPE_SHORT =
:CFunc type - short
DL
- TYPE_INT =
:CFunc type - int
DL
- TYPE_LONG =
:CFunc type - long
DL
- TYPE_LONG_LONG =
:CFunc type - long long
DL
- TYPE_FLOAT =
:CFunc type - float
DL
- TYPE_DOUBLE =
:CFunc type - double
DL
- ALIGN_VOIDP =
The Offset of a struct void* and a void*
INT2NUM(ALIGN_VOIDP)
- ALIGN_CHAR =
The Offset of a struct char and a char
INT2NUM(ALIGN_CHAR)
- ALIGN_SHORT =
The Offset of a struct short and a short
INT2NUM(ALIGN_SHORT)
- ALIGN_INT =
The Offset of a struct int and a int
INT2NUM(ALIGN_INT)
- ALIGN_LONG =
The Offset of a struct long and a long
INT2NUM(ALIGN_LONG)
- ALIGN_LONG_LONG =
The Offset of a struct long long and a long long
INT2NUM(ALIGN_LONG_LONG)
- ALIGN_FLOAT =
The Offset of a struct float and a float
INT2NUM(ALIGN_FLOAT)
- ALIGN_DOUBLE =
The Offset of a struct double and a double
INT2NUM(ALIGN_DOUBLE)
- SIZEOF_VOIDP =
OS Dependent - sizeof(void*)
INT2NUM(sizeof(void*))
- SIZEOF_CHAR =
OS Dependent - sizeof(char)
INT2NUM(sizeof(char))
- SIZEOF_SHORT =
OS Dependent - sizeof(short)
INT2NUM(sizeof(short))
- SIZEOF_INT =
OS Dependent - sizeof(int)
INT2NUM(sizeof(int))
- SIZEOF_LONG =
OS Dependent - sizeof(long)
INT2NUM(sizeof(long))
- SIZEOF_LONG_LONG =
OS Dependent - sizeof(long long)
INT2NUM(sizeof(LONG_LONG))
- SIZEOF_FLOAT =
OS Dependent - sizeof(float)
INT2NUM(sizeof(float))
- SIZEOF_DOUBLE =
OS Dependent - sizeof(double)
INT2NUM(sizeof(double))
- RUBY_FREE =
Address of the ruby_xfree() function
PTR2NUM(ruby_xfree)
- BUILD_RUBY_PLATFORM =
Platform built against (i.e. "x86_64-linux", etc.)
See also RUBY_PLATFORM
rb_str_new2(RUBY_PLATFORM)
- BUILD_RUBY_VERSION =
Ruby Version built. (i.e. "1.9.3")
See also RUBY_VERSION
rb_str_new2(RUBY_VERSION)
- NULL =
A NULL pointer
rb_dlptr_new(0, 0, 0)
- SEM =
The mutual exclusion (Mutex) semaphore for the DL module
Mutex.new
- CdeclCallbackProcs =
A Hash of callback Procs
Uses Fiddle
tmp
- CdeclCallbackAddrs =
A Hash of the addresses of callback Proc
Uses Fiddle
tmp
- StdcallCallbackProcs =
A Hash of Stdcall callback Procs
Uses Fiddle on win32
tmp
- StdcallCallbackAddrs =
A Hash of the addresses of Stdcall callback Procs
Uses Fiddle on win32
tmp
Class Method Summary collapse
- .dlopen ⇒ Object
- .dlunwrap ⇒ Object
- .dlwrap ⇒ Object
- .fiddle? ⇒ Boolean
-
.free(addr) ⇒ Object
Free the memory at address
addr
. -
.malloc ⇒ Object
Allocate
size
bytes of memory and return the integer memory address for the allocated memory. -
.realloc(addr, size) ⇒ Object
Change the size of the memory allocated at the memory location
addr
tosize
bytes.
Instance Method Summary collapse
- #remove_callback_internal(proc_entry, addr_entry, addr, ctype = nil) ⇒ Object
- #remove_cdecl_callback(addr, ctype = nil) ⇒ Object (also: #remove_callback)
- #remove_stdcall_callback(addr, ctype = nil) ⇒ Object
- #set_callback_internal(proc_entry, addr_entry, argc, ty, abi = nil, &cbp) ⇒ Object
- #set_cdecl_callback(ty, argc, &cbp) ⇒ Object (also: #set_callback)
- #set_stdcall_callback(ty, argc, &cbp) ⇒ Object
Class Method Details
.dlopen ⇒ Object
20 21 22 23 24 |
# File 'dl.c', line 20
VALUE
rb_dl_dlopen(int argc, VALUE argv[], VALUE self)
{
return rb_class_new_instance(argc, argv, rb_cDLHandle);
}
|
.dlunwrap ⇒ Object
74 75 76 77 78 79 |
# File 'dl.c', line 74
VALUE
rb_dl_ptr2value(VALUE self, VALUE addr)
{
rb_secure(4);
return (VALUE)NUM2PTR(addr);
}
|
.dlwrap ⇒ Object
81 82 83 84 85 |
# File 'dl.c', line 81
VALUE
rb_dl_value2ptr(VALUE self, VALUE val)
{
return PTR2NUM((void*)val);
}
|
.fiddle? ⇒ Boolean
9 10 11 |
# File 'lib/dl.rb', line 9 def self.fiddle? Object.const_defined?(:Fiddle) end |
.free(addr) ⇒ Object
Free the memory at address addr
64 65 66 67 68 69 70 71 72 |
# File 'dl.c', line 64
VALUE
rb_dl_free(VALUE self, VALUE addr)
{
void *ptr = NUM2PTR(addr);
rb_secure(4);
ruby_xfree(ptr);
return Qnil;
}
|
.malloc ⇒ Object
Allocate size
bytes of memory and return the integer memory address for the allocated memory.
32 33 34 35 36 37 38 39 40 |
# File 'dl.c', line 32
VALUE
rb_dl_malloc(VALUE self, VALUE size)
{
void *ptr;
rb_secure(4);
ptr = (void*)ruby_xmalloc(NUM2INT(size));
return PTR2NUM(ptr);
}
|
.realloc(addr, size) ⇒ Object
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.
49 50 51 52 53 54 55 56 57 |
# File 'dl.c', line 49
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);
}
|
Instance Method Details
#remove_callback_internal(proc_entry, addr_entry, addr, ctype = nil) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File '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 |
#remove_cdecl_callback(addr, ctype = nil) ⇒ Object Also known as: remove_callback
102 103 104 |
# File 'lib/dl/callback.rb', line 102 def remove_cdecl_callback(addr, ctype = nil) remove_callback_internal(CdeclCallbackProcs, CdeclCallbackAddrs, addr, ctype) end |
#remove_stdcall_callback(addr, ctype = nil) ⇒ Object
106 107 108 |
# File 'lib/dl/callback.rb', line 106 def remove_stdcall_callback(addr, ctype = nil) remove_callback_internal(StdcallCallbackProcs, StdcallCallbackAddrs, addr, ctype) end |
#set_callback_internal(proc_entry, addr_entry, argc, ty, abi = nil, &cbp) ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File '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 |
#set_cdecl_callback(ty, argc, &cbp) ⇒ Object Also known as: set_callback
58 59 60 |
# File 'lib/dl/callback.rb', line 58 def set_cdecl_callback(ty, argc, &cbp) set_callback_internal(CdeclCallbackProcs, CdeclCallbackAddrs, argc, ty, &cbp) end |
#set_stdcall_callback(ty, argc, &cbp) ⇒ Object
62 63 64 65 66 67 68 |
# File '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 |