Module: DL
- Defined in:
- dl.c,
lib/dl.rb,
lib/dl/func.rb,
lib/dl/pack.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,
dl.c
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
- 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
- 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
- TYPE_SIZE_T =
:CFunc type - size_t
DL
- TYPE_SSIZE_T =
:CFunc type - ssize_t
DL
- TYPE_PTRDIFF_T =
:CFunc type - ptrdiff_t
DL
- TYPE_INTPTR_T =
:CFunc type - intptr_t
DL
- TYPE_UINTPTR_T =
:CFunc type - uintptr_t
DL
- ALIGN_VOIDP =
The alignment size of a void*
INT2NUM(ALIGN_VOIDP)
- ALIGN_CHAR =
The alignment size of a char
INT2NUM(ALIGN_CHAR)
- ALIGN_SHORT =
The alignment size of a short
INT2NUM(ALIGN_SHORT)
- ALIGN_INT =
The alignment size of an int
INT2NUM(ALIGN_INT)
- ALIGN_LONG =
The alignment size of a long
INT2NUM(ALIGN_LONG)
- ALIGN_LONG_LONG =
The alignment size of a long long
INT2NUM(ALIGN_LONG_LONG)
- ALIGN_FLOAT =
The alignment size of a float
INT2NUM(ALIGN_FLOAT)
- ALIGN_DOUBLE =
The alignment size of a double
INT2NUM(ALIGN_DOUBLE)
- ALIGN_SIZE_T =
The alignment size of a size_t
INT2NUM(ALIGN_OF(size_t))
- ALIGN_SSIZE_T =
same as size_t
INT2NUM(ALIGN_OF(size_t))
- ALIGN_PTRDIFF_T =
The alignment size of a ptrdiff_t
INT2NUM(ALIGN_OF(ptrdiff_t))
- ALIGN_INTPTR_T =
The alignment size of a intptr_t
INT2NUM(ALIGN_OF(intptr_t))
- ALIGN_UINTPTR_T =
The alignment size of a uintptr_t
INT2NUM(ALIGN_OF(uintptr_t))
- SIZEOF_VOIDP =
size of a void*
INT2NUM(sizeof(void*))
- SIZEOF_CHAR =
size of a char
INT2NUM(sizeof(char))
- SIZEOF_SHORT =
size of a short
INT2NUM(sizeof(short))
- SIZEOF_INT =
size of an int
INT2NUM(sizeof(int))
- SIZEOF_LONG =
size of a long
INT2NUM(sizeof(long))
- SIZEOF_LONG_LONG =
size of a long long
INT2NUM(sizeof(LONG_LONG))
- SIZEOF_FLOAT =
size of a float
INT2NUM(sizeof(float))
- SIZEOF_DOUBLE =
size of a double
INT2NUM(sizeof(double))
- SIZEOF_SIZE_T =
size of a size_t
INT2NUM(sizeof(size_t))
- SIZEOF_SSIZE_T =
same as size_t
INT2NUM(sizeof(size_t))
- SIZEOF_PTRDIFF_T =
size of a ptrdiff_t
INT2NUM(sizeof(ptrdiff_t))
- SIZEOF_INTPTR_T =
size of a intptr_t
INT2NUM(sizeof(intptr_t))
- SIZEOF_UINTPTR_T =
size of a uintptr_t
INT2NUM(sizeof(uintptr_t))
- 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)
Class Method Summary collapse
-
.dlopen(so_lib) ⇒ Object
An interface to the dynamic linking loader.
-
.dlunwrap(addr) ⇒ Object
Returns the hexadecimal representation of a memory pointer address
addr
. -
.dlwrap(val) ⇒ Object
Returns a memory pointer of a function’s hexadecimal address location
val
. -
.fiddle? ⇒ Boolean
Returns true if DL is using Fiddle, the libffi wrapper.
-
.free(addr) ⇒ Object
Free the memory at address
addr
. -
.malloc(size) ⇒ 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(so_lib) ⇒ Object
An interface to the dynamic linking loader
This is a shortcut to DL::Handle.new and takes the same arguments.
Example:
libc_so = "/lib64/libc.so.6"
=> "/lib64/libc.so.6"
libc = DL.dlopen(libc_so)
=> #<DL::Handle:0x00000000e05b00>
67 68 69 70 71 |
# File 'dl.c', line 67
VALUE
rb_dl_dlopen(int argc, VALUE argv[], VALUE self)
{
return rb_class_new_instance(argc, argv, rb_cDLHandle);
}
|
.dlunwrap(addr) ⇒ Object
Returns the hexadecimal representation of a memory pointer address addr
Example:
lib = DL.dlopen('/lib64/libc-2.15.so')
=> #<DL::Handle:0x00000001342460>
lib['strcpy'].to_s(16)
=> "7f59de6dd240"
DL.dlunwrap(DL.dlwrap(lib['strcpy'].to_s(16)))
=> "7f59de6dd240"
134 135 136 137 138 |
# File 'dl.c', line 134
VALUE
rb_dl_ptr2value(VALUE self, VALUE addr)
{
return (VALUE)NUM2PTR(addr);
}
|
.dlwrap(val) ⇒ Object
Returns a memory pointer of a function’s hexadecimal address location val
Example:
lib = DL.dlopen('/lib64/libc-2.15.so')
=> #<DL::Handle:0x00000001342460>
DL.dlwrap(lib['strcpy'].to_s(16))
=> 25522520
153 154 155 156 157 |
# File 'dl.c', line 153
VALUE
rb_dl_value2ptr(VALUE self, VALUE val)
{
return PTR2NUM((void*)val);
}
|
.fiddle? ⇒ Boolean
Returns true if DL is using Fiddle, the libffi wrapper.
12 13 14 |
# File 'lib/dl.rb', line 12 def self.fiddle? Object.const_defined?(:Fiddle) end |
.free(addr) ⇒ Object
Free the memory at address addr
109 110 111 112 113 114 115 116 |
# File 'dl.c', line 109
VALUE
rb_dl_free(VALUE self, VALUE addr)
{
void *ptr = NUM2PTR(addr);
ruby_xfree(ptr);
return Qnil;
}
|
.malloc(size) ⇒ Object
Allocate size
bytes of memory and return the integer memory address for the allocated memory.
79 80 81 82 83 84 85 86 |
# File 'dl.c', line 79
VALUE
rb_dl_malloc(VALUE self, VALUE size)
{
void *ptr;
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.
95 96 97 98 99 100 101 102 |
# File 'dl.c', line 95
VALUE
rb_dl_realloc(VALUE self, VALUE addr, VALUE size)
{
void *ptr = NUM2PTR(addr);
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 |