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 ]


      # Convert :foo to the native type
      arg_types.map! { |e| find_type(e) }
      options = Hash.new
      options[:convention] = defined?(@ffi_convention) ? @ffi_convention : :default
      options[:type_map] = defined?(@ffi_typedefs) ? @ffi_typedefs : nil
      options[:enums] = defined?(@ffi_enum_map) ? @ffi_enum_map : nil
      options.merge!(opts) if opts.is_a?(Hash)

      # Try to locate the function in any of the libraries
      invokers = []
      load_error = nil
      ffi_libraries.each do |lib|
        begin
          invokers << FFI.create_invoker(lib, cname.to_s, arg_types, find_type(ret_type), options)
        rescue LoadError => ex
          load_error = ex
        end if invokers.empty?
        end
      invoker = invokers.compact.shift
      raise load_error if load_error && invoker.nil?
      #raise FFI::NotFoundError.new(cname.to_s, *libraries) unless invoker
      invoker.attach(self, mname.to_s)
      invoker # Return a version that can be called via #call
    end
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 ]


      # Convert :foo to the native type
      arg_types.map! { |e| find_type(e) }
      options = Hash.new
      options[:convention] = defined?(@ffi_convention) ? @ffi_convention : :default
      options[:type_map] = defined?(@ffi_typedefs) ? @ffi_typedefs : nil
      options[:enums] = defined?(@ffi_enum_map) ? @ffi_enum_map : nil
      options.merge!(opts) if opts.is_a?(Hash)

      # Try to locate the function in any of the libraries
      invokers = []
      load_error = nil
      ffi_libraries.each do |lib|
        begin
          invokers << FFI.create_invoker(lib, cname.to_s, arg_types, find_type(ret_type), options)
        rescue LoadError => ex
          load_error = ex
        end if invokers.empty?
        end
      invoker = invokers.compact.shift
      raise load_error if load_error && invoker.nil?
      #raise FFI::NotFoundError.new(cname.to_s, *libraries) unless invoker
      invoker.attach(self, mname.to_s)
      invoker # Return a version that can be called via #call
    end
Attach C function +name+ to this module.

 If you want to provide an alternate name for the module function, supply
 it after the +name+, otherwise the C function name will be used.

 After the +name+, the C function argument types are provided as an Array.

 The C function return type is provided last.