def define_api(name, camel_name, effective_names, params, returns, options)
      params, returns = generate_signature(params.dup, returns)

      ffi_lib *(ffi_libraries.map(&:name) << options[:dll]) if options[:dll]
      libs = ffi_libraries.map(&:name)

      alternative = options.delete(:alternative) # Function may have alternative signature
      effective_name = if alternative

        alt_params, alt_returns, condition = generate_signature(*alternative)
        api = function name, params, returns,
                       options.merge( camel_only: true, camel_name: "#{camel_name}Original")
        alt_api = function name, alt_params, alt_returns,
                           options.merge( camel_only: true, camel_name: "#{camel_name}Alternative")

        define_method camel_name do |*args|
          (condition[*args] ? alt_api : api).call(*args)
        end
        module_function camel_name
        public camel_name
        api.effective_name
      else
        effective_names.inject(nil) do |func, effective_name|
          func || begin
            # Try to attach basic CamelCase method via FFI
            attach_function(camel_name, effective_name, params.dup, returns)
            effective_name
          rescue FFI::NotFoundError
            nil
          end
        end
      end

      raise Win::Errors::NotFoundError.new(name, libs) unless effective_name

      # Create API object that holds information about defined and effective function names, params, etc.
      # This object is further used by enhanced snake_case method to reflect on underlying API and
      # intelligently call it.
      API.new(namespace, camel_name, effective_name, params, returns, libs)
    end
def define_api(name, camel_name, effective_names, params, returns, options)
      params, returns = generate_signature(params.dup, returns)

      ffi_lib *(ffi_libraries.map(&:name) << options[:dll]) if options[:dll]
      libs = ffi_libraries.map(&:name)

      alternative = options.delete(:alternative) # Function may have alternative signature
      effective_name = if alternative

        alt_params, alt_returns, condition = generate_signature(*alternative)
        api = function name, params, returns,
                       options.merge( camel_only: true, camel_name: "#{camel_name}Original")
        alt_api = function name, alt_params, alt_returns,
                           options.merge( camel_only: true, camel_name: "#{camel_name}Alternative")

        define_method camel_name do |*args|
          (condition[*args] ? alt_api : api).call(*args)
        end
        module_function camel_name
        public camel_name
        api.effective_name
      else
        effective_names.inject(nil) do |func, effective_name|
          func || begin
            # Try to attach basic CamelCase method via FFI
            attach_function(camel_name, effective_name, params.dup, returns)
            effective_name
          rescue FFI::NotFoundError
            nil
          end
        end
      end

      raise Win::Errors::NotFoundError.new(name, libs) unless effective_name

      # Create API object that holds information about defined and effective function names, params, etc.
      # This object is further used by enhanced snake_case method to reflect on underlying API and
      # intelligently call it.
      API.new(namespace, camel_name, effective_name, params, returns, libs)
    end
Defines CamelCase method calling Win32 API function, and associated API object