123456789_123456789_123456789_123456789_123456789_

Class: FFI::Function

Relationships & Source Files
Namespace Children
Modules:
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
Instance Chain:
Inherits: FFI::Pointer
Defined in: ext/ffi_c/Function.c,
lib/ffi/function.rb

Constant Summary

AbstractMemory - Inherited

LONG_MAX

Pointer - Inherited

NULL, SIZE

Class Method Summary

Pointer - Inherited

.new

A new instance of Pointer.

.size

Return the size of a pointer on the current platform, in bytes.

Instance Attribute Summary

Pointer - Inherited

AbstractMemory - Inherited

#size_limit?

Return true if self has a size limit.

Instance Method Summary

RegisterAttach - Included

Pointer - Inherited

#+, #==,
#address

Alias for Pointer#to_i.

#free,
#initialize_copy

This method is internally used by #dup and #clone.

#inspect

Alias for Pointer#to_s.

#order

Get or set self‘s endianness.

#read

Read pointer’s contents as #type

#read_array_of_type

Read an array of #type of length length.

#read_string

Read pointer’s contents as a string, or the first len bytes of the equivalent string if len is not nil.

#read_string_length

Read the first len bytes of pointer’s contents as a string.

#read_string_to_null

Read pointer’s contents as a string.

#slice, #to_i, #to_ptr, #to_s, #type_size,
#write

Write value of type #type to pointer’s content.

#write_array_of_type

Write ary in pointer’s contents as #type.

#write_string

Write str in pointer’s contents, or first len bytes if len is not nil.

#write_string_length

Write len first bytes of str in pointer’s contents.

AbstractMemory - Inherited

Constructor Details

.new(return_type, param_types, options = {}) { |i| ... }) {|i| ... } ⇒ self .new(return_type, param_types, proc, options = {}) ⇒ self

A new Function instance.

Define a function from a Proc or a block.

Parameters:

  • return_type (Type, Symbol)

    return type for the function

  • param_types (Array<Type, Symbol>)

    array of parameters types

  • options (Hash)

    see Type for available options

[ GitHub ]

  
# File 'ext/ffi_c/Function.c', line 344

static VALUE
function_initialize(int argc, VALUE* argv, VALUE self)
{

    VALUE rbReturnType = Qnil, rbParamTypes = Qnil, rbProc = Qnil, rbOptions = Qnil;
    VALUE rbFunctionInfo = Qnil;
    VALUE infoArgv[3];
    int nargs;

    nargs = rb_scan_args(argc, argv, "22", &rbReturnType, &rbParamTypes, &rbProc, &rbOptions);

    /*
     * Callback with block,
     * e.g. Function.new(:int, [ :int ]) { |i| blah }
     * or   Function.new(:int, [ :int ], { :convention => :stdcall }) { |i| blah }
     */
    if (rb_block_given_p()) {
        if (nargs > 3) {
            rb_raise(rb_eArgError, "cannot create function with both proc/address and block");
        }
        rbOptions = rbProc;
        rbProc = rb_block_proc();
    } else {
        /* Callback with proc, or Function with address
         * e.g. Function.new(:int, [ :int ], Proc.new { |i| })
         *      Function.new(:int, [ :int ], Proc.new { |i| }, { :convention => :stdcall })
         *      Function.new(:int, [ :int ], addr)
         *      Function.new(:int, [ :int ], addr, { :convention => :stdcall })
         */
    }

    infoArgv[0] = rbReturnType;
    infoArgv[1] = rbParamTypes;
    infoArgv[2] = rbOptions;
    rbFunctionInfo = rb_class_new_instance(rbOptions != Qnil ? 3 : 2, infoArgv, rbffi_FunctionTypeClass);

    function_init(self, rbFunctionInfo, rbProc);

    return self;
}

Instance Attribute Details

#autorelease=(autorelease) (rw) Set({autorelease} attribute (See {Pointer}).)

[ GitHub ]

  
# File 'ext/ffi_c/Function.c', line 546

static VALUE
function_set_autorelease(VALUE self, VALUE autorelease)
{
    Function* fn;

    rb_check_frozen(self);
    TypedData_Get_Struct(self, Function, &function_data_type, fn);

    fn->autorelease = RTEST(autorelease);

    return self;
}

#autorelease (rw) Get({autorelease} attribute.) Synonymous(for {#autorelease?}.)

Alias for #autorelease.

Instance Method Details

#attach(m, name) #a(Function)

[ GitHub ]

  
# File 'ext/ffi_c/Function.c', line 508

static VALUE
function_attach(VALUE self, VALUE module, VALUE name)
{
    Function* fn;

    StringValue(name);
    TypedData_Get_Struct(self, Function, &function_data_type, fn);

    if (fn->info->parameterCount == -1) {
        rb_raise(rb_eRuntimeError, "cannot attach variadic functions");
        return Qnil;
    }

    if (!rb_obj_is_kind_of(module, rb_cModule)) {
        rb_raise(rb_eRuntimeError, "trying to attach function to non-module");
        return Qnil;
    }

    if (fn->methodHandle == NULL) {
        fn->methodHandle = rbffi_MethodHandle_Alloc(fn->info, fn->base.memory.address);
    }

    rb_define_singleton_method(module, StringValueCStr(name),
            rbffi_MethodHandle_CodeAddress(fn->methodHandle), -1);


    rb_define_method(module, StringValueCStr(name),
            rbffi_MethodHandle_CodeAddress(fn->methodHandle), -1);

    return self;
}

#autorelease (rw) Get({autorelease} attribute.) Synonymous(for {#autorelease?}.)
Also known as: #autorelease?

[ GitHub ]

  
# File 'ext/ffi_c/Function.c', line 559

static VALUE
function_autorelease_p(VALUE self)
{
    Function* fn;

    TypedData_Get_Struct(self, Function, &function_data_type, fn);

    return fn->autorelease ? Qtrue : Qfalse;
}

#call(*args) #the(function)

[ GitHub ]

  
# File 'ext/ffi_c/Function.c', line 491

static VALUE
function_call(int argc, VALUE* argv, VALUE self)
{
    Function* fn;

    TypedData_Get_Struct(self, Function, &function_data_type, fn);

    return (*fn->info->invoke)(argc, argv, fn->base.memory.address, fn->info);
}

#free #memory(allocated)

[ GitHub ]

  
# File 'ext/ffi_c/Function.c', line 584

static VALUE
function_release(VALUE self)
{
    Function* fn;

    TypedData_Get_Struct(self, Function, &function_data_type, fn);

    if (fn->closure == NULL) {
        rb_raise(rb_eRuntimeError, "cannot free function which was not allocated");
    }

    rbffi_Closure_Free(fn->closure);
    fn->closure = NULL;

    return self;
}

#initialize_copy(other) NOT(CALL)

[ GitHub ]

  
# File 'ext/ffi_c/Function.c', line 390

static VALUE
function_initialize_copy(VALUE self, VALUE other)
{
    rb_raise(rb_eRuntimeError, "cannot duplicate function instances");
    return Qnil;
}

#param_typesArray<FFI::Type>

Retrieve Array of parameter types

This method returns an Array of ::FFI types accepted as function parameters.

[ GitHub ]

  
# File 'lib/ffi/function.rb', line 49

def param_types
  type.param_types
end

#return_typeFFI::Type

Retrieve the return type of the function

This method returns ::FFI type returned by the function.

[ GitHub ]

  
# File 'lib/ffi/function.rb', line 40

def return_type
  type.return_type
end

#type (private)

[ GitHub ]

  
# File 'ext/ffi_c/Function.c', line 569

static VALUE
function_type(VALUE self)
{
    Function* fn;

    TypedData_Get_Struct(self, Function, &function_data_type, fn);

    return fn->rbFunctionInfo;
}