首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Fiddle::Handle

Parent:Object

Fiddle :: Handle是访问动态库的方式

Setup

代码语言:javascript
复制
libc_so = "/lib64/libc.so.6"
=> "/lib64/libc.so.6"
@handle = Fiddle::Handle.new(libc_so)
=> #<Fiddle::Handle:0x00000000d69ef8>

Setup, with flags

代码语言:javascript
复制
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

符号的地址

代码语言:javascript
复制
strcpy_addr = @handle['strcpy']
=> 140062278451968

或是以下方式:

代码语言:javascript
复制
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()了解更多信息。

代码语言:javascript
复制
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。

代码语言:javascript
复制
lib = Fiddle::Handle.new

缺省值取决于操作系统,并为已加载的所有库提供句柄。例如,在大多数情况下,您可以使用它来访问libc函数或ruby函数rb_str_new

代码语言:javascript
复制
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

代码语言:javascript
复制
static VALUE
rb_fiddle_handle_s_sym(VALUE self, VALUE sym)
{
    return fiddle_handle_sym(RTLD_NEXT, sym);
}

公共实例方法

sym(name) Show source

获取地址作为名为的函数的整数name

代码语言:javascript
复制
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异常。

代码语言:javascript
复制
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()了解更多信息。

代码语言:javascript
复制
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()的调用。

代码语言:javascript
复制
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()的调用。

代码语言:javascript
复制
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的函数的整数。

代码语言:javascript
复制
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

返回此句柄的内存地址。

代码语言:javascript
复制
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);
}

扫码关注腾讯云开发者

领取腾讯云代金券

http://www.vxiaotou.com