Class: Fiddle::Handle
- Inherits:
-
Object
- Object
- Fiddle::Handle
- Defined in:
- ext/fiddle/handle.c,
lib/fiddle/ffi_backend.rb,
ext/fiddle/handle.c
Overview
The Fiddle::Handle is the manner to access the dynamic library
Example
Setup
libc_so = "/lib64/libc.so.6"
=> "/lib64/libc.so.6"
@handle = Fiddle::Handle.new(libc_so)
=> #<Fiddle::Handle:0x00000000d69ef8>
Setup, with flags
libc_so = "/lib64/libc.so.6"
=> "/lib64/libc.so.6"
@handle = Fiddle::Handle.new(libc_so, Fiddle::RTLD_LAZY | Fiddle::RTLD_GLOBAL)
=> #<Fiddle::Handle:0x00000000d69ef8>
See RTLD_LAZY and RTLD_GLOBAL
Addresses to symbols
strcpy_addr = @handle['strcpy']
=> 140062278451968
or
strcpy_addr = @handle.sym('strcpy')
=> 140062278451968
Constant Summary collapse
- RTLD_GLOBAL =
:Handle flag.
The symbols defined by this library will be made available for symbol resolution of subsequently loaded libraries.
rtld Fiddle
- 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 Fiddle
- 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 Fiddle.dlopen returns. If this cannot be done an error is returned.
rtld Fiddle
- DEFAULT =
A predefined pseudo-handle of RTLD_DEFAULT
Which will find the first occurrence of the desired symbol using the default library search order
predefined_fiddle_handle(RTLD_DEFAULT)
- 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.
predefined_fiddle_handle(RTLD_NEXT)
Class Method Summary collapse
-
.[](sym) ⇒ Object
call-seq: sym(name).
-
.sym(sym) ⇒ Object
call-seq: sym(name).
- .sym_defined?(sym) ⇒ Boolean
Instance Method Summary collapse
-
#[](sym) ⇒ Object
call-seq: sym(name).
-
#close ⇒ Object
Close this handle.
-
#close_enabled? ⇒ Boolean
Returns
true
if dlclose() will be called when this handle is garbage collected. -
#disable_close ⇒ Object
Disable a call to dlclose() when this handle is garbage collected.
-
#enable_close ⇒ Object
Enable a call to dlclose() when this handle is garbage collected.
-
#file_name ⇒ Object
Returns the file name of this handle.
-
#new(library = nil, flags = Fiddle::RTLD_LAZY|Fiddle::RTLD_GLOBAL) ⇒ Object
constructor
Create a new handler that opens
library
withflags
. -
#sym(sym) ⇒ Object
call-seq: sym(name).
- #sym_defined?(sym) ⇒ Boolean
-
#to_i ⇒ Object
Returns the memory address for this handle.
-
#to_ptr ⇒ Object
Returns the Fiddle::Pointer of this handle.
Constructor Details
#new(library = nil, flags = Fiddle::RTLD_LAZY|Fiddle::RTLD_GLOBAL) ⇒ Object
Create a new handler that opens library
with flags
.
If no library
is specified or nil
is given, DEFAULT is used, which is the equivalent to RTLD_DEFAULT. See man 3 dlopen
for more.
lib = Fiddle::Handle.new
The default is dependent on OS, and provide a handle for all libraries already loaded. For example, in most cases you can use this to access libc
functions, or ruby functions like rb_str_new
.
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'ext/fiddle/handle.c', line 136 def initialize(libname = nil, flags = RTLD_LAZY | RTLD_GLOBAL) begin @lib = FFI::DynamicLibrary.open(libname, flags) rescue LoadError, RuntimeError # LoadError for JRuby, RuntimeError for TruffleRuby raise DLError, "Could not open #{libname}" end @open = true begin yield(self) ensure self.close end if block_given? end |
Class Method Details
.[](sym) ⇒ Object
call-seq: sym(name)
Get the address as an Integer for the function named name
. The function is searched via dlsym on RTLD_NEXT.
See man(3) dlsym() for more info.
324 325 326 |
# File 'ext/fiddle/handle.c', line 324 def self.[](func) self.sym(func) end |
.sym(sym) ⇒ Object
call-seq: sym(name)
Get the address as an Integer for the function named name
. The function is searched via dlsym on RTLD_NEXT.
See man(3) dlsym() for more info.
324 325 326 |
# File 'ext/fiddle/handle.c', line 324 def self.sym(func) DEFAULT.sym(func) end |
.sym_defined?(sym) ⇒ Boolean
394 395 396 |
# File 'ext/fiddle/handle.c', line 394 def self.sym_defined?(func) DEFAULT.sym_defined?(func) end |
Instance Method Details
#[](sym) ⇒ Object
call-seq: sym(name)
Get the address as an Integer for the function named name
.
294 295 296 |
# File 'ext/fiddle/handle.c', line 294 def [](func) sym(func) end |
#close ⇒ Object
Close this handle.
Calling close more than once will raise a Fiddle::DLError exception.
70 71 72 73 74 |
# File 'ext/fiddle/handle.c', line 70 def close raise DLError.new("closed handle") unless @open @open = false 0 end |
#close_enabled? ⇒ Boolean
Returns true
if dlclose() will be called when this handle is garbage collected.
See man(3) dlclose() for more info.
246 247 248 |
# File 'ext/fiddle/handle.c', line 246 def close_enabled? @enable_close end |
#disable_close ⇒ Object
Disable a call to dlclose() when this handle is garbage collected.
229 230 231 |
# File 'ext/fiddle/handle.c', line 229 def disable_close @enable_close = false end |
#enable_close ⇒ Object
Enable a call to dlclose() when this handle is garbage collected.
214 215 216 |
# File 'ext/fiddle/handle.c', line 214 def enable_close @enable_close = true end |
#file_name ⇒ Object
Returns the file name of this handle.
449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 |
# File 'ext/fiddle/handle.c', line 449
static VALUE
rb_fiddle_handle_file_name(VALUE self)
{
struct dl_handle *fiddle_handle;
TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle);
#if defined(HAVE_DLINFO) && defined(HAVE_CONST_RTLD_DI_LINKMAP)
{
struct link_map *lm = NULL;
int res = dlinfo(fiddle_handle->ptr, RTLD_DI_LINKMAP, &lm);
if (res == 0 && lm != NULL) {
return rb_str_new_cstr(lm->l_name);
}
else {
#if defined(HAVE_DLERROR)
rb_raise(rb_eFiddleDLError, "could not get handle file name: %s", dlerror());
#else
rb_raise(rb_eFiddleDLError, "could not get handle file name");
#endif
}
}
#elif defined(HAVE_GETMODULEFILENAME)
{
char filename[MAX_PATH];
DWORD res = GetModuleFileName(fiddle_handle->ptr, filename, MAX_PATH);
if (res == 0) {
rb_raise(rb_eFiddleDLError, "could not get handle file name: %s", dlerror());
}
return rb_str_new_cstr(filename);
}
#else
(void)fiddle_handle;
return Qnil;
#endif
}
|
#sym(sym) ⇒ Object
call-seq: sym(name)
Get the address as an Integer for the function named name
.
294 295 296 297 298 299 300 |
# File 'ext/fiddle/handle.c', line 294 def sym(func) raise TypeError.new("invalid function name") unless func.is_a?(String) raise DLError.new("closed handle") unless @open address = @lib.find_function(func) raise DLError.new("unknown symbol #{func}") if address.nil? || address.null? address.to_i end |
#sym_defined?(sym) ⇒ Boolean
409 410 411 412 413 414 |
# File 'ext/fiddle/handle.c', line 409 def sym_defined?(func) raise TypeError.new("invalid function name") unless func.is_a?(String) raise DLError.new("closed handle") unless @open address = @lib.find_function(func) !address.nil? && !address.null? end |
#to_i ⇒ Object
Returns the memory address for this handle.
262 263 264 265 266 267 268 269 |
# File 'ext/fiddle/handle.c', line 262
static VALUE
rb_fiddle_handle_to_i(VALUE self)
{
struct dl_handle *fiddle_handle;
TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle);
return PTR2NUM(fiddle_handle->ptr);
}
|
#to_ptr ⇒ Object
Returns the Fiddle::Pointer of this handle.
276 277 278 279 280 281 282 283 |
# File 'ext/fiddle/handle.c', line 276
static VALUE
rb_fiddle_handle_to_ptr(VALUE self)
{
struct dl_handle *fiddle_handle;
TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle);
return rb_fiddle_ptr_new_wrap(fiddle_handle->ptr, 0, 0, self, 0);
}
|