Fiddle::Handle
class Fiddle::Handle
Parent:Object
Fiddle :: Handle是访问动态库的方式
例
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
符号的地址
strcpy_addr = @handle['strcpy']
=> 140062278451968
或是以下方式:
strcpy_addr = @handle.sym('strcpy')
=> 140062278451968
常量
DEFAULT
DEFAULT
预定义的RTLD_DEFAULT伪句柄
它将使用默认库搜索顺序查找所需符号的第一个匹配项
NEXT
NEXT
RTLD_NEXT的预定义伪句柄
它将在当前库之后的搜索顺序中查找下一次出现的函数。
RTLD_GLOBAL
RTLD_GLOBAL
rtld Fiddle::Handle flag.
由该库定义的符号将可用于随后加载的库的符号解析。
RTLD_LAZY
RTLD_LAZY
rtld Fiddle::Handle flag.
执行延迟绑定。只有在执行引用它们的代码时才解析符号。如果符号从未被引用,那么它永远不会被解析。(惰性绑定仅针对函数引用执行;对于变量的引用总是在加载该库时立即绑定。)
RTLD_NOW
RTLD_NOW
rtld Fiddle::Handle flag.
如果指定了此值或环境变量LD_BIND_NOW设置为非空字符串,则库中的所有未定义符号都将在Fiddle#dlopen返回前解析。如果无法完成,则返回错误。
公共类方法
sym(name) Show source
获取地址作为名为的函数的整数name
。该函数通过RTLD_NEXT上的dlsym进行搜索。
请参阅man(3)dlsym()了解更多信息。
static VALUE
rb_fiddle_handle_s_sym(VALUE self, VALUE sym)
{
return fiddle_handle_sym(RTLD_NEXT, sym
}
new(library = nil, flags = Fiddle::RTLD_LAZY | Fiddle::RTLD_GLOBAL) Show source
创建一个用标志打开库的新处理程序。
如果未指定库或给出nil,则使用DEFAULT,这与RTLD_DEFAULT等效。可参阅 man 3 dlopen。
lib = Fiddle::Handle.new
缺省值取决于操作系统,并为已加载的所有库提供句柄。例如,在大多数情况下,您可以使用它来访问libc
函数或ruby函数rb_str_new
。
static VALUE
rb_fiddle_handle_initialize(int argc, VALUE argv[], VALUE self)
{
void *ptr;
struct dl_handle *fiddle_handle;
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 : SafeStringValueCStr(lib
cflag = RTLD_LAZY | RTLD_GLOBAL;
break;
case 2:
clib = NIL_P(lib) ? NULL : SafeStringValueCStr(lib
cflag = NUM2INT(flag
break;
default:
rb_bug("rb_fiddle_handle_new"
}
#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
(void)cflag;
ptr = w32_coredll(
# endif
}
else
#endif
ptr = dlopen(clib, cflag
#if defined(HAVE_DLERROR)
if( !ptr && (err = dlerror()) ){
rb_raise(rb_eFiddleError, "%s", err
}
#else
if( !ptr ){
err = dlerror(
rb_raise(rb_eFiddleError, "%s", err
}
#endif
TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle
if( fiddle_handle->ptr && fiddle_handle->open && fiddle_handle->enable_close ){
dlclose(fiddle_handle->ptr
}
fiddle_handle->ptr = ptr;
fiddle_handle->open = 1;
fiddle_handle->enable_close = 0;
if( rb_block_given_p() ){
rb_ensure(rb_yield, self, rb_fiddle_handle_close, self
}
return Qnil;
}
sym(name) Show source
获取地址作为名为的函数的整数name
。
static VALUE
rb_fiddle_handle_s_sym(VALUE self, VALUE sym)
{
return fiddle_handle_sym(RTLD_NEXT, sym
}
公共实例方法
sym(name) Show source
获取地址作为名为的函数的整数name
。
static VALUE
rb_fiddle_handle_sym(VALUE self, VALUE sym)
{
struct dl_handle *fiddle_handle;
TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle
if( ! fiddle_handle->open ){
rb_raise(rb_eFiddleError, "closed handle"
}
return fiddle_handle_sym(fiddle_handle->ptr, sym
}
关闭显示源代码
关闭此句柄。
多次调用关闭会引发Fiddle :: DLError异常。
static VALUE
rb_fiddle_handle_close(VALUE self)
{
struct dl_handle *fiddle_handle;
TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle
if(fiddle_handle->open) {
int ret = dlclose(fiddle_handle->ptr
fiddle_handle->open = 0;
/* Check dlclose for successful return value */
if(ret) {
#if defined(HAVE_DLERROR)
rb_raise(rb_eFiddleError, "%s", dlerror()
#else
rb_raise(rb_eFiddleError, "could not close handle"
#endif
}
return INT2NUM(ret
}
rb_raise(rb_eFiddleError, "dlclose() called too many times"
UNREACHABLE;
}
close_enabled? Show source
如果在处理废物回收时调用dlclose(),则返回true。
请参阅man(3)dlclose()了解更多信息。
static VALUE
rb_fiddle_handle_close_enabled_p(VALUE self)
{
struct dl_handle *fiddle_handle;
TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle
if(fiddle_handle->enable_close) return Qtrue;
return Qfalse;
}
disable_close Show source
当这个句柄被废物收集时,禁用对dlclose()的调用。
static VALUE
rb_fiddle_handle_disable_close(VALUE self)
{
struct dl_handle *fiddle_handle;
TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle
fiddle_handle->enable_close = 0;
return Qnil;
}
enable_close Show source
当这个句柄被废物收集时启用对dlclose()的调用。
static VALUE
rb_fiddle_handle_enable_close(VALUE self)
{
struct dl_handle *fiddle_handle;
TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle
fiddle_handle->enable_close = 1;
return Qnil;
}
sym(name) Show source
获取名称为name的函数的整数。
static VALUE
rb_fiddle_handle_sym(VALUE self, VALUE sym)
{
struct dl_handle *fiddle_handle;
TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle
if( ! fiddle_handle->open ){
rb_raise(rb_eFiddleError, "closed handle"
}
return fiddle_handle_sym(fiddle_handle->ptr, sym
}
to_i Show source
返回此句柄的内存地址。
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
}