In Files

  • dl/cfunc.c

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

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

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

sym(name) click to toggle source

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));
}
            
initialize(lib = nil, flags = DL::RTLD_LAZY | DL::RTLD_GLOBAL) click to toggle source

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 : StringValuePtr(lib);
        cflag = RTLD_LAZY | RTLD_GLOBAL;
        break;
      case 2:
        clib = NIL_P(lib) ? NULL : StringValuePtr(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;
}
            
sym(name) click to toggle source
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

sym(name) click to toggle source

Get the address as an Integer for the function named name.

 
               VALUE
rb_dlhandle_sym(VALUE self, VALUE sym)
{
    struct dl_handle *dlhandle;

    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, StringValueCStr(sym));
}
            
close click to toggle source

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");
}
            
close_enabled? click to toggle source

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_close click to toggle source

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_close click to toggle source

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;
}
            
sym(name) click to toggle source
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;

    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, StringValueCStr(sym));
}
            
to_i click to toggle source

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);
}
            

Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.

If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.

If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.

If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.

blog comments powered by Disqus