In Files

  • dl/lib/dl/import.rb

DL::Importer

DL::Importer includes 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 'dl'
require 'dl/import'

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

Public Instance Methods

[](name) click to toggle source
 
               # File dl/lib/dl/import.rb, line 203
def [](name)
  @func_map[name]
end
            
bind(signature, *opts, &blk) click to toggle source
 
               # File dl/lib/dl/import.rb, line 154
    def bind(signature, *opts, &blk)
      @type_alias ||= nil
      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)
      when :temp, :temporal
        f = create_temp_function(name, ctype, argtype, h[:call_type])
      when :carried
        f = create_carried_function(name, ctype, argtype, h[:call_type], h[:carrier])
      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("        def #{name}(*args,&block)
          @func_map['#{name}'].call(*args,&block)
        end
", file, line)
      module_function(name)
      f
    end
            
bind_function(name, ctype, argtype, call_type = nil, &block) click to toggle source
 
               # File dl/lib/dl/import.rb, line 244
def bind_function(name, ctype, argtype, call_type = nil, &block)
  if DL.fiddle?
    klass = Function.instance_eval { class_fiddle_closure_cfunc }
    abi = Function.instance_eval { call_type_to_abi(call_type) }
    closure = Class.new(klass) {
      define_method(:call, block)
    }.new(ctype, argtype, abi, name)

    Function.new(closure, argtype, abi)
  else
    f = Function.new(CFunc.new(0, ctype, name, call_type || :cdecl), argtype)
    f.bind(&block)
    f
  end
end
            
create_carried_function(name, ctype, argtype, call_type = nil, n = 0) click to toggle source
 
               # File dl/lib/dl/import.rb, line 264
def create_carried_function(name, ctype, argtype, call_type = nil, n = 0)
  CarriedFunction.new(CFunc.new(0, ctype, name, call_type || :cdecl), argtype, n)
end
            
create_temp_function(name, ctype, argtype, call_type = nil) click to toggle source
 
               # File dl/lib/dl/import.rb, line 260
def create_temp_function(name, ctype, argtype, call_type = nil)
  TempFunction.new(CFunc.new(0, ctype, name, call_type || :cdecl), argtype)
end
            
create_value(ty, val=nil) click to toggle source
 
               # File dl/lib/dl/import.rb, line 207
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
 
               # File dl/lib/dl/import.rb, line 55
def dlload(*libs)
  handles = libs.collect{|lib|
    case lib
    when nil
      nil
    when Handle
      lib
    when Importer
      lib.handlers
    else
      begin
        DL.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
 
               # File dl/lib/dl/import.rb, line 131
    def extern(signature, *opts)
      @type_alias ||= nil
      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("        def #{name}(*args, &block)
          @func_map['#{name}'].call(*args,&block)
        end
", file, line)
      module_function(name)
      f
    end
            
handler() click to toggle source
 
               # File dl/lib/dl/import.rb, line 223
def handler
  defined?(@handler) or raise "call dlload before importing symbols and functions"
  @handler
end
            
import_function(name, ctype, argtype, call_type = nil) click to toggle source
 
               # File dl/lib/dl/import.rb, line 236
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(CFunc.new(addr, ctype, name, call_type || :cdecl), argtype)
end
            
import_symbol(name) click to toggle source
 
               # File dl/lib/dl/import.rb, line 228
def import_symbol(name)
  addr = handler.sym(name)
  if( !addr )
    raise(DLError, "cannot find the symbol: #{name}")
  end
  CPtr.new(addr)
end
            
import_value(ty, addr) click to toggle source
 
               # File dl/lib/dl/import.rb, line 217
def import_value(ty, addr)
  s = struct([ty + " value"])
  ptr = s.new(addr)
  return ptr
end
            
sizeof(ty) click to toggle source
 
               # File dl/lib/dl/import.rb, line 81
def sizeof(ty)
  @type_alias ||= nil
  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_LON
    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 CPtr[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 dl/lib/dl/import.rb, line 188
def struct(signature)
  @type_alias ||= nil
  tys, mems = parse_struct_signature(signature, @type_alias)
  DL::CStructBuilder.create(CStruct, tys, mems)
end
            
typealias(alias_type, orig_type) click to toggle source
 
               # File dl/lib/dl/import.rb, line 77
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 dl/lib/dl/import.rb, line 197
def union(signature)
  @type_alias ||= nil
  tys, mems = parse_struct_signature(signature, @type_alias)
  DL::CStructBuilder.create(CUnion, tys, mems)
end
            
value(ty, val=nil) click to toggle source
Alias for: create_value

Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.

If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.

If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.

If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.

blog comments powered by Disqus