Class: FFI::Function

### Home Classes Methods

### In Files

- ext/ffi_c/ffi.c

### Parent

FFI::Pointer

### Methods

- ::new
- #attach
- #autorelease
- #autorelease=
- #autorelease?
- #call
- #free
- #initialize_copy

### Files

- Makefile
- LICENSE
- compile
- configure
- depcomp
- stamp-vti
- install-sh
- libtool-version
- mdate-sh
- missing

### Class/Module Index

Quicksearch

- FFI
- FFI::AutoPointer
- FFI::AutoPointer::CallableReleaser
- FFI::AutoPointer::DefaultReleaser
- FFI::AutoPointer::Releaser
- FFI::ConstGenerator
- FFI::ConstGenerator::Constant
- FFI::Enum
- FFI::Enums
- FFI::Function
- FFI::FunctionType
- FFI::Generator
- FFI::Generator::Task
- FFI::IO
- FFI::LastError
- FFI::ManagedStruct
- FFI::MemoryPointer
- FFI::NativeType
- FFI::Platform
- FFI::PlatformError
- FFI::Pointer
- FFI::StrPtrConverter
- FFI::Struct
- FFI::Struct::InlineArray
- FFI::Struct::ManagedStructConverter
- FFI::StructByReference
- FFI::StructByValue
- FFI::StructGenerator
- FFI::StructGenerator::Field
- FFI::StructLayout
- FFI::StructLayout::Array
- FFI::StructLayout::Enum
- FFI::StructLayout::Field
- FFI::StructLayout::Function
- FFI::StructLayout::InnerStruct
- FFI::StructLayout::Mapped
- FFI::StructLayout::Number
- FFI::StructLayout::Pointer
- FFI::StructLayout::String
- FFI::StructLayoutBuilder
- FFI::Type
- FFI::Type::Builtin
- FFI::TypesGenerator
- FFI::Union
- FFI::VariadicInvoker

No matching classes.

# FFI::Function

### Public Class Methods

new(p1, p2, p3 = v3, p4 = v4) click to toggle source

@param [Type, Symbol] return_type return type for the function @param [Array<Type, Symbol>] param_types array of parameters types @param [Hash] options see {FFI::FunctionType} for available options @return [self] A new Function instance.

Define a function from a Proc or a block.

@overload initialize(return_type, param_types, options = {}) { |i| ... }

    @yieldparam i parameters for the function

@overload initialize(return_type, param_types, proc, options = {})

    @param [Proc] proc

    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;
    }

### Public Instance Methods

attach(m, name) click to toggle source
@param [Module] m
@param [String] name
@return [self]
Attach a Function to the Module +m+ as +name+.

    static VALUE
    function_attach(VALUE self, VALUE module, VALUE name)
    {
        Function* fn;
        char var[1024];

        Data_Get_Struct(self, Function, 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);
        }

        /*
         * Stash the Function in a module variable so it does not get garbage collected
         */
        snprintf(var, sizeof(var), "@@%s", StringValueCStr(name));
        rb_cv_set(module, var, self);

        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() click to toggle source

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

        Data_Get_Struct(self, Function, fn);

        return fn->autorelease ? Qtrue : Qfalse;
    }

autorelease = autorelease click to toggle source
@param [Boolean] autorelease
@return [self]
Set +autorelease+ attribute (See {Pointer}).

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

        Data_Get_Struct(self, Function, fn);

        fn->autorelease = RTEST(autorelease);

        return self;
    }

autorelease?() click to toggle source

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

        Data_Get_Struct(self, Function, fn);

        return fn->autorelease ? Qtrue : Qfalse;
    }

call(*args) click to toggle source
@param [Array] args function arguments
@return [FFI::Type]
Call the function

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

        Data_Get_Struct(self, Function, fn);

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

free click to toggle source
@return [self]
Free memory allocated by Function.

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

        Data_Get_Struct(self, Function, 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) click to toggle source
@return [nil]
DO NOT CALL THIS METHOD

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

[Validate]

Generated with the Darkfish Rdoc Generator 2.