class DL::Handle
The DL::Handle is the manner to access the dynamic library
Example¶ ↑
Setup¶ ↑
libc_so = "/lib64/libc.so.6" => "/lib64/libc.so.6" @handle = DL::Handle.new(libc_so) => #<DL::Handle:0x00000000d69ef8>
Setup, with flags¶ ↑
libc_so = "/lib64/libc.so.6" => "/lib64/libc.so.6" @handle = DL::Handle.new(libc_so, DL::RTLD_LAZY | DL::RTLD_GLOBAL) => #<DL::Handle:0x00000000d69ef8>
Addresses to symbols¶ ↑
strcpy_addr = @handle['strcpy'] => 140062278451968
or
strcpy_addr = @handle.sym('strcpy') => 140062278451968
Constants
- DEFAULT
-
A predefined pseudo-handle of RTLD_DEFAULT
Which will find the first occurrence of the desired symbol using the default library search order
- NEXT
-
A predefined pseudo-handle of RTLD_NEXT
Which will find the next occurrence of a function in the search order after the current library.
Public Class Methods
Get the address as an Integer for the
function named name
.
VALUE rb_dlhandle_s_sym(VALUE self, VALUE sym) { return dlhandle_sym(RTLD_NEXT, StringValueCStr(sym)); }
Create a new handler that opens library named lib
with
flags
. If no library is specified, RTLD_DEFAULT is used.
VALUE rb_dlhandle_initialize(int argc, VALUE argv[], VALUE self) { void *ptr; struct dl_handle *dlhandle; VALUE lib, flag; char *clib; int cflag; const char *err; switch( rb_scan_args(argc, argv, "02", &lib, &flag) ){ case 0: clib = NULL; cflag = RTLD_LAZY | RTLD_GLOBAL; break; case 1: clib = NIL_P(lib) ? NULL : SafeStringValuePtr(lib); cflag = RTLD_LAZY | RTLD_GLOBAL; break; case 2: clib = NIL_P(lib) ? NULL : SafeStringValuePtr(lib); cflag = NUM2INT(flag); break; default: rb_bug("rb_dlhandle_new"); } rb_secure(2); #if defined(_WIN32) if( !clib ){ HANDLE rb_libruby_handle(void); ptr = rb_libruby_handle(); } else if( STRCASECMP(clib, "libc") == 0 # ifdef RUBY_COREDLL || STRCASECMP(clib, RUBY_COREDLL) == 0 || STRCASECMP(clib, RUBY_COREDLL".dll") == 0 # endif ){ # ifdef _WIN32_WCE ptr = dlopen("coredll.dll", cflag); # else ptr = w32_coredll(); # endif } else #endif ptr = dlopen(clib, cflag); #if defined(HAVE_DLERROR) if( !ptr && (err = dlerror()) ){ rb_raise(rb_eDLError, "%s", err); } #else if( !ptr ){ err = dlerror(); rb_raise(rb_eDLError, "%s", err); } #endif TypedData_Get_Struct(self, struct dl_handle, &dlhandle_data_type, dlhandle); if( dlhandle->ptr && dlhandle->open && dlhandle->enable_close ){ dlclose(dlhandle->ptr); } dlhandle->ptr = ptr; dlhandle->open = 1; dlhandle->enable_close = 0; if( rb_block_given_p() ){ rb_ensure(rb_yield, self, rb_dlhandle_close, self); } return Qnil; }
Document-method: []
Get the address as an Integer for the
function named name
.
VALUE rb_dlhandle_s_sym(VALUE self, VALUE sym) { return dlhandle_sym(RTLD_NEXT, StringValueCStr(sym)); }
Public Instance Methods
Get the address as an Integer for the
function named name
.
VALUE rb_dlhandle_sym(VALUE self, VALUE sym) { struct dl_handle *dlhandle; const char *name; name = SafeStringValuePtr(sym); TypedData_Get_Struct(self, struct dl_handle, &dlhandle_data_type, dlhandle); if( ! dlhandle->open ){ rb_raise(rb_eDLError, "closed handle"); } return dlhandle_sym(dlhandle->ptr, name); }
Close this DL::Handle. Calling close more than once will raise a DL::DLError exception.
VALUE rb_dlhandle_close(VALUE self) { struct dl_handle *dlhandle; TypedData_Get_Struct(self, struct dl_handle, &dlhandle_data_type, dlhandle); if(dlhandle->open) { int ret = dlclose(dlhandle->ptr); dlhandle->open = 0; /* Check dlclose for successful return value */ if(ret) { #if defined(HAVE_DLERROR) rb_raise(rb_eDLError, "%s", dlerror()); #else rb_raise(rb_eDLError, "could not close handle"); #endif } return INT2NUM(ret); } rb_raise(rb_eDLError, "dlclose() called too many times"); UNREACHABLE; }
Returns true
if dlclose() will be called when this DL::Handle is garbage collected.
static VALUE rb_dlhandle_close_enabled_p(VALUE self) { struct dl_handle *dlhandle; TypedData_Get_Struct(self, struct dl_handle, &dlhandle_data_type, dlhandle); if(dlhandle->enable_close) return Qtrue; return Qfalse; }
Disable a call to dlclose() when this DL::Handle is garbage collected.
VALUE rb_dlhandle_disable_close(VALUE self) { struct dl_handle *dlhandle; TypedData_Get_Struct(self, struct dl_handle, &dlhandle_data_type, dlhandle); dlhandle->enable_close = 0; return Qnil; }
Enable a call to dlclose() when this DL::Handle is garbage collected.
VALUE rb_dlhandle_enable_close(VALUE self) { struct dl_handle *dlhandle; TypedData_Get_Struct(self, struct dl_handle, &dlhandle_data_type, dlhandle); dlhandle->enable_close = 1; return Qnil; }
Document-method: []
Get the address as an Integer for the
function named name
.
VALUE rb_dlhandle_sym(VALUE self, VALUE sym) { struct dl_handle *dlhandle; const char *name; name = SafeStringValuePtr(sym); TypedData_Get_Struct(self, struct dl_handle, &dlhandle_data_type, dlhandle); if( ! dlhandle->open ){ rb_raise(rb_eDLError, "closed handle"); } return dlhandle_sym(dlhandle->ptr, name); }
Returns the memory address for this handle.
VALUE rb_dlhandle_to_i(VALUE self) { struct dl_handle *dlhandle; TypedData_Get_Struct(self, struct dl_handle, &dlhandle_data_type, dlhandle); return PTR2NUM(dlhandle); }