def attach_function(mname, a2, a3, a4=nil, a5 = nil)
cname, arg_types, ret_type, opts = (a4 && (a2.is_a?(String) || a2.is_a?(Symbol))) ? [ a2, a3, a4, a5 ] : [ mname.to_s, a2, a3, a4 ]
arg_types.map! { |e| find_type(e) }
options = {
:convention => defined?(@ffi_convention) ? @ffi_convention : :default,
:type_map => defined?(@ffi_typedefs) ? @ffi_typedefs : nil,
:blocking => defined?(@blocking) && @blocking,
:enums => defined?(@ffi_enums) ? @ffi_enums : nil,
}
@blocking = false
options.merge!(opts) if opts && opts.is_a?(Hash)
invokers = []
ffi_libraries.each do |lib|
if invokers.empty?
begin
function = lib.find_function(cname.to_s)
raise LoadError unless function
invokers << if arg_types.length > 0 && arg_types[arg_types.length - 1] == FFI::NativeType::VARARGS
VariadicInvoker.new(function, arg_types, find_type(ret_type), options)
else
Function.new(find_type(ret_type), arg_types, function, options)
end
rescue LoadError => ex
end
end
end
invoker = invokers.compact.shift
raise FFI::NotFoundError.new(cname.to_s, ffi_libraries.map { |lib| lib.name }) unless invoker
invoker.attach(self, mname.to_s)
invoker
end