module FFI::Library
def ffi_lib(*names)
-
(LoadError)
- if a library cannot be opened
Returns:
-
(Array
-)
Parameters:
-
names
(Array
) -- names of libraries to load
def ffi_lib(*names) raise LoadError.new("library names list must not be empty") if names.empty? lib_flags = defined?(@ffi_lib_flags) ? @ffi_lib_flags : FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_LOCAL ffi_libs = names.map do |name| if name == FFI::CURRENT_PROCESS FFI::DynamicLibrary.open(nil, FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_LOCAL) else libnames = (name.is_a?(::Array) ? name : [ name ]).map { |n| [ n, FFI.map_library_name(n) ].uniq }.flatten.compact lib = nil errors = {} libnames.each do |libname| begin orig = libname lib = FFI::DynamicLibrary.open(libname, lib_flags) break if lib rescue Exception => ex ldscript = false if ex.message =~ /(([^ \t()])+\.so([^ \t:()])*):([ \t])*(invalid ELF header|file too short|invalid file format)/ if File.read($1) =~ /(?:GROUP|INPUT) *\( *([^ \)]+)/ libname = $1 ldscript = true end end # TODO better library lookup logic unless libname.to_s.start_with?("/") path = ['/usr/lib/','/usr/local/lib/'].find do |pth| File.exist?(pth + libname) end if path libname = path + libname retry end end if ldscript retry else libr = (orig == libname ? orig : "#{orig} #{libname}") errors[libr] = ex end end end if lib.nil? raise LoadError.new(errors.values.join(".\n")) end # return the found lib lib end end @ffi_libs = ffi_libs end