Class: FFI::DynamicLibrary
- Inherits:
-
Object
- Object
- FFI::DynamicLibrary
- Defined in:
- lib/ffi/dynamic_library.rb,
ext/ffi_c/DynamicLibrary.c
Defined Under Namespace
Classes: Symbol
Constant Summary collapse
- SEARCH_PATH =
%w[/usr/lib /usr/local/lib /opt/local/lib]
- SEARCH_PATH_MESSAGE =
"Searched in <system library path>, #{SEARCH_PATH.join(', ')}".freeze
Instance Attribute Summary collapse
- #name ⇒ Object readonly
Class Method Summary collapse
-
.last_error ⇒ String
Library’s last error string.
- .load_library(name, flags) ⇒ Object private
-
.open(libname, libflags) ⇒ FFI::DynamicLibrary
Open a library.
- .try_load(libname, flags, errors) ⇒ Object private
Instance Method Summary collapse
-
#find_function(name) ⇒ FFI::DynamicLibrary::Symbol
Library function symbol.
-
#find_symbol(name) ⇒ FFI::DynamicLibrary::Symbol
Library symbol.
-
#find_variable(name) ⇒ FFI::DynamicLibrary::Symbol
Library variable symbol.
-
#initialize(libname, libflags) ⇒ FFI::DynamicLibrary
constructor
A new DynamicLibrary instance.
-
#last_error ⇒ String
Library’s last error string.
Constructor Details
#initialize(libname, libflags) ⇒ FFI::DynamicLibrary
A new DynamicLibrary instance.
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'ext/ffi_c/DynamicLibrary.c', line 136
static VALUE
library_initialize(VALUE self, VALUE libname, VALUE libflags)
{
Library* library;
int flags;
Check_Type(libflags, T_FIXNUM);
TypedData_Get_Struct(self, Library, &rbffi_library_data_type, library);
flags = libflags != Qnil ? NUM2UINT(libflags) : 0;
library->handle = dl_open(libname != Qnil ? StringValueCStr(libname) : NULL, flags);
if (library->handle == NULL) {
char errmsg[1024];
dl_error(errmsg, sizeof(errmsg));
rb_raise(rb_eLoadError, "Could not open library '%s': %s",
libname != Qnil ? StringValueCStr(libname) : "[current process]",
errmsg);
}
#ifdef __CYGWIN__
// On Cygwin 1.7.17 "dlsym(dlopen(0,0), 'getpid')" fails. (dlerror: "No such process")
// As a workaround we can use "dlsym(RTLD_DEFAULT, 'getpid')" instead.
// Since 0 == RTLD_DEFAULT we won't call dl_close later.
if (libname == Qnil) {
dl_close(library->handle);
library->handle = RTLD_DEFAULT;
}
#endif
rb_iv_set(self, "@name", libname != Qnil ? rb_str_new_frozen(libname) : rb_str_new2("[current process]"));
rb_obj_freeze(self);
return self;
}
|
Instance Attribute Details
#name ⇒ Object (readonly)
Class Method Details
.last_error ⇒ String
Returns library’s last error string.
187 188 189 190 191 192 193 |
# File 'ext/ffi_c/DynamicLibrary.c', line 187
static VALUE
library_dlerror(VALUE self)
{
char errmsg[1024];
dl_error(errmsg, sizeof(errmsg));
return rb_str_new2(errmsg);
}
|
.load_library(name, flags) ⇒ Object (private)
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/ffi/dynamic_library.rb', line 40 def self.load_library(name, flags) if name == FFI::CURRENT_PROCESS FFI::DynamicLibrary.open(nil, RTLD_LAZY | RTLD_LOCAL) else flags ||= RTLD_LAZY | RTLD_LOCAL libnames = (name.is_a?(::Array) ? name : [name]) libnames = libnames.map(&:to_s).map { |n| [n, FFI.map_library_name(n)].uniq }.flatten.compact errors = [] libnames.each do |libname| lib = try_load(libname, flags, errors) return lib if lib unless libname.start_with?("/") || FFI::Platform.windows? SEARCH_PATH.each do |prefix| path = "#{prefix}/#{libname}" if File.exist?(path) lib = try_load(path, flags, errors) return lib if lib end end end end raise LoadError, [*errors, SEARCH_PATH_MESSAGE].join(".\n") end end |
.open(libname, libflags) ⇒ FFI::DynamicLibrary
Open a library.
122 123 124 125 126 |
# File 'ext/ffi_c/DynamicLibrary.c', line 122
static VALUE
library_open(VALUE klass, VALUE libname, VALUE libflags)
{
return library_initialize(library_allocate(klass), libname, libflags);
}
|
.try_load(libname, flags, errors) ⇒ Object (private)
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/ffi/dynamic_library.rb', line 70 def self.try_load(libname, flags, errors) begin lib = FFI::DynamicLibrary.open(libname, flags) return lib if lib # LoadError for C ext & JRuby, RuntimeError for TruffleRuby rescue LoadError, RuntimeError => ex if ex. =~ /(([^ \t()])+\.so([^ \t:()])*):([ \t])*(invalid ELF header|file too short|invalid file format)/ if File.binread($1) =~ /(?:GROUP|INPUT) *\( *([^ \)]+)/ return try_load($1, flags, errors) end end errors << ex nil end end |
Instance Method Details
#find_function(name) ⇒ FFI::DynamicLibrary::Symbol
Returns library function symbol.
170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'ext/ffi_c/DynamicLibrary.c', line 170
static VALUE
library_dlsym(VALUE self, VALUE name)
{
Library* library;
void* address = NULL;
Check_Type(name, T_STRING);
TypedData_Get_Struct(self, Library, &rbffi_library_data_type, library);
address = dl_sym(library->handle, StringValueCStr(name));
return address != NULL ? symbol_new(self, address, name) : Qnil;
}
|
#find_symbol(name) ⇒ FFI::DynamicLibrary::Symbol
Returns library symbol.
170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'ext/ffi_c/DynamicLibrary.c', line 170
static VALUE
library_dlsym(VALUE self, VALUE name)
{
Library* library;
void* address = NULL;
Check_Type(name, T_STRING);
TypedData_Get_Struct(self, Library, &rbffi_library_data_type, library);
address = dl_sym(library->handle, StringValueCStr(name));
return address != NULL ? symbol_new(self, address, name) : Qnil;
}
|
#find_variable(name) ⇒ FFI::DynamicLibrary::Symbol
Returns library variable symbol.
170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'ext/ffi_c/DynamicLibrary.c', line 170
static VALUE
library_dlsym(VALUE self, VALUE name)
{
Library* library;
void* address = NULL;
Check_Type(name, T_STRING);
TypedData_Get_Struct(self, Library, &rbffi_library_data_type, library);
address = dl_sym(library->handle, StringValueCStr(name));
return address != NULL ? symbol_new(self, address, name) : Qnil;
}
|
#last_error ⇒ String
Returns library’s last error string.
187 188 189 190 191 192 193 |
# File 'ext/ffi_c/DynamicLibrary.c', line 187
static VALUE
library_dlerror(VALUE self)
{
char errmsg[1024];
dl_error(errmsg, sizeof(errmsg));
return rb_str_new2(errmsg);
}
|