Module: Fiddle::Importer (Ruby 2.3.7)
Description: Module : Fiddle::Importer - Ruby 2.3.7

- Home
- Core 2.3.7
- Std-lib 2.3.7
- Downloads

Support for the Ruby 2.3 series has ended. See here for reference.

### Home Classes Methods

### In Files

- fiddle/lib/fiddle/import.rb

### Methods

- #[]
- #bind
- #bind_function
- #create_value
- #dlload
- #extern
- #handler
- #import_function
- #import_symbol
- #import_value
- #sizeof
- #struct
- #typealias
- #union
- #value

### Included Modules

- Fiddle
- Fiddle::CParser

### Class/Module Index

Quicksearch

- Fiddle
- Fiddle::BasicTypes
- Fiddle::CParser
- Fiddle::CStruct
- Fiddle::CStructBuilder
- Fiddle::CStructEntity
- Fiddle::CUnion
- Fiddle::CUnionEntity
- Fiddle::Closure
- Fiddle::Closure::BlockCaller
- Fiddle::CompositeHandler
- Fiddle::DLError
- Fiddle::Function
- Fiddle::Handle
- Fiddle::Importer
- Fiddle::Pointer
- Fiddle::Win32Types

No matching classes.

# Fiddle::Importer

A DSL that provides the means to dynamically load libraries and build modules around them including calling extern functions within the C library that has been loaded.

## Example¶ ↑

    require 'fiddle'
    require 'fiddle/import'

    module LibSum
      extend Fiddle::Importer
      dlload './libsum.so'
      extern 'double sum(double*, int)'
      extern 'double split(double)'
    end

### Public Instance Methods

[](name) click to toggle source

Returns the function mapped to `name`, that was created by either #extern or #bind

                   # File fiddle/lib/fiddle/import.rb, line 229
    def [](name)
      @func_map[name]
    end

bind(signature, *opts, &blk) click to toggle source

Creates a global method from the given C `signature` using the given `opts` as bind parameters with the given block.

                   # File fiddle/lib/fiddle/import.rb, line 185
        def bind(signature, *opts, &blk)
          name, ctype, argtype = parse_signature(signature, @type_alias)
          h = parse_bind_options(opts)
          case h[:callback_type]
          when :bind, nil
            f = bind_function(name, ctype, argtype, h[:call_type], &blk)
          else
            raise(RuntimeError, "unknown callback type: #{h[:callback_type]}")
          end
          @func_map[name] = f
          #define_method(name){|*args,&block| f.call(*args,&block)}
          begin
            /^(.+?):(\d+)/ =~ caller.first
            file, line = $1, $2.to_i
          rescue
            file, line = __FILE__, __LINE__+3
          end
          module_eval(<<-EOS, file, line)
            def #{name}(*args,&block)
              @func_map['#{name}'].call(*args,&block)
            end
          EOS
          module_function(name)
          f
        end

bind_function(name, ctype, argtype, call_type = nil, &block) click to toggle source

Returns a new closure wrapper for the `name` function.

- `ctype` is the return type of the function

- `argtype` is an Array of arguments, passed to the callback function

- `call_type` is the abi of the closure

- `block` is passed to the callback

See Fiddle::Closure

                   # File fiddle/lib/fiddle/import.rb, line 305
    def bind_function(name, ctype, argtype, call_type = nil, &block)
      abi = CALL_TYPE_TO_ABI[call_type]
      closure = Class.new(Fiddle::Closure) {
        define_method(:call, block)
      }.new(ctype, argtype, abi)

      Function.new(closure, argtype, ctype, abi, name: name)
    end

create_value(ty, val=nil) click to toggle source

Creates a class to wrap the C struct with the value `ty`

See also #struct

                   # File fiddle/lib/fiddle/import.rb, line 236
    def create_value(ty, val=nil)
      s = struct([ty + " value"])
      ptr = s.malloc()
      if( val )
        ptr.value = val
      end
      return ptr
    end

Also aliased as: value
dlload(*libs) click to toggle source

Creates an array of handlers for the given `libs`, can be an instance of Fiddle::Handle, Fiddle::Importer, or will create a new instance of Fiddle::Handle using Fiddle.dlopen

Raises a DLError if the library cannot be loaded.

See Fiddle.dlopen

                   # File fiddle/lib/fiddle/import.rb, line 72
    def dlload(*libs)
      handles = libs.collect{|lib|
        case lib
        when nil
          nil
        when Handle
          lib
        when Importer
          lib.handlers
        else
          begin
            Fiddle.dlopen(lib)
          rescue DLError
            raise(DLError, "can't load #{lib}")
          end
        end
      }.flatten()
      @handler = CompositeHandler.new(handles)
      @func_map = {}
      @type_alias = {}
    end

extern(signature, *opts) click to toggle source

Creates a global method from the given C `signature`.

                   # File fiddle/lib/fiddle/import.rb, line 161
        def extern(signature, *opts)
          symname, ctype, argtype = parse_signature(signature, @type_alias)
          opt = parse_bind_options(opts)
          f = import_function(symname, ctype, argtype, opt[:call_type])
          name = symname.gsub(/@.+/,'')
          @func_map[name] = f
          # define_method(name){|*args,&block| f.call(*args,&block)}
          begin
            /^(.+?):(\d+)/ =~ caller.first
            file, line = $1, $2.to_i
          rescue
            file, line = __FILE__, __LINE__+3
          end
          module_eval(<<-EOS, file, line)
            def #{name}(*args, &block)
              @func_map['#{name}'].call(*args,&block)
            end
          EOS
          module_function(name)
          f
        end

handler() click to toggle source

The Fiddle::CompositeHandler instance

Will raise an error if no handlers are open.

                   # File fiddle/lib/fiddle/import.rb, line 258
    def handler
      @handler or raise "call dlload before importing symbols and functions"
    end

import_function(name, ctype, argtype, call_type = nil) click to toggle source

Returns a new Fiddle::Function instance at the memory address of the given `name` function.

Raises a DLError if the `name` doesn't exist.

- `argtype` is an Array of arguments, passed to the `name` function.

- `ctype` is the return type of the function

- `call_type` is the ABI of the function

See also Fiddle:Function.new

See Fiddle::CompositeHandler#sym and Fiddle::Handler.sym

                   # File fiddle/lib/fiddle/import.rb, line 288
    def import_function(name, ctype, argtype, call_type = nil)
      addr = handler.sym(name)
      if( !addr )
        raise(DLError, "cannot find the function: #{name}()")
      end
      Function.new(addr, argtype, ctype, CALL_TYPE_TO_ABI[call_type],
                   name: name)
    end

import_symbol(name) click to toggle source

Returns a new Fiddle::Pointer instance at the memory address of the given `name` symbol.

Raises a DLError if the `name` doesn't exist.

See Fiddle::CompositeHandler#sym and Fiddle::Handle.sym

                   # File fiddle/lib/fiddle/import.rb, line 268
    def import_symbol(name)
      addr = handler.sym(name)
      if( !addr )
        raise(DLError, "cannot find the symbol: #{name}")
      end
      Pointer.new(addr)
    end

import_value(ty, addr) click to toggle source

Returns a new instance of the C struct with the value `ty` at the `addr` address.

                   # File fiddle/lib/fiddle/import.rb, line 248
    def import_value(ty, addr)
      s = struct([ty + " value"])
      ptr = s.new(addr)
      return ptr
    end

sizeof(ty) click to toggle source

Returns the sizeof `ty`, using Fiddle::CParser#parse_ctype to determine the C type and the appropriate Fiddle constant.

                   # File fiddle/lib/fiddle/import.rb, line 101
    def sizeof(ty)
      case ty
      when String
        ty = parse_ctype(ty, @type_alias).abs()
        case ty
        when TYPE_CHAR
          return SIZEOF_CHAR
        when TYPE_SHORT
          return SIZEOF_SHORT
        when TYPE_INT
          return SIZEOF_INT
        when TYPE_LONG
          return SIZEOF_LONG
        when TYPE_LONG_LONG
          return SIZEOF_LONG_LONG
        when TYPE_FLOAT
          return SIZEOF_FLOAT
        when TYPE_DOUBLE
          return SIZEOF_DOUBLE
        when TYPE_VOIDP
          return SIZEOF_VOIDP
        else
          raise(DLError, "unknown type: #{ty}")
        end
      when Class
        if( ty.instance_methods().include?(:to_ptr) )
          return ty.size()
        end
      end
      return Pointer[ty].size()
    end

struct(signature) click to toggle source

Creates a class to wrap the C struct described by `signature`.

    MyStruct = struct ['int i', 'char c']

                   # File fiddle/lib/fiddle/import.rb, line 214
    def struct(signature)
      tys, mems = parse_struct_signature(signature, @type_alias)
      Fiddle::CStructBuilder.create(CStruct, tys, mems)
    end

typealias(alias_type, orig_type) click to toggle source

Sets the type alias for `alias_type` as `orig_type`

                   # File fiddle/lib/fiddle/import.rb, line 95
    def typealias(alias_type, orig_type)
      @type_alias[alias_type] = orig_type
    end

union(signature) click to toggle source

Creates a class to wrap the C union described by `signature`.

    MyUnion = union ['int i', 'char c']

                   # File fiddle/lib/fiddle/import.rb, line 222
    def union(signature)
      tys, mems = parse_struct_signature(signature, @type_alias)
      Fiddle::CStructBuilder.create(CUnion, tys, mems)
    end

value(ty, val=nil) click to toggle source
Alias for: create_value