In Files

  • dl/lib/dl/import.rb
  • dl/lib/dl/struct.rb

DL::Importable::Internal

Public Instance Methods

[](name) click to toggle source
 
               # File dl/lib/dl/import.rb, line 18
def [](name)
  return @SYM[name.to_s][0]
end
            
_args_() click to toggle source
 
               # File dl/lib/dl/import.rb, line 179
def _args_
  return @args
end
            
_retval_() click to toggle source
 
               # File dl/lib/dl/import.rb, line 183
def _retval_
  return @retval
end
            
callback(proto) click to toggle source

example:

callback "int method_name(int, char*)"
 
               # File dl/lib/dl/import.rb, line 66
def callback(proto)
  func,ret,args = parse_cproto(proto)

  init_types()
  init_sym()

  rty,renc,rdec = @types.encode_return_type(ret)
  if( !rty )
    raise(TypeError, "unsupported type: #{ret}")
  end
  ty,enc,dec = encode_argument_types(args)
  symty = rty + ty

  module_eval("module_function :#{func}")
  sym = module_eval([
    "DL::callback(\"#{symty}\"){|*args|",
    "  sym,rdec,enc,dec  = @SYM['#{func}']",
    "  args = enc.call(args) if enc",
    "  r,rs = #{func}(*args)",
    "  r  = renc.call(r) if rdec",
    "  rs = dec.call(rs) if (dec && rs)",
    "  @retval = r",
    "  @args   = rs",
    "  r",
    "}",
  ].join("\n"))

  @SYM[func] = [sym,rdec,enc,dec]

  return sym
end
            
define_struct(contents) click to toggle source
 
               # File dl/lib/dl/struct.rb, line 8
def define_struct(contents)
  init_types()
  Struct.new(@types, contents)
end
            
Also aliased as: struct
define_union(contents) click to toggle source
 
               # File dl/lib/dl/struct.rb, line 14
def define_union(contents)
  init_types()
  Union.new(@types, contents)
end
            
Also aliased as: union
dlload(*libnames) click to toggle source
 
               # File dl/lib/dl/import.rb, line 22
def dlload(*libnames)
  if( !defined?(@LIBS) )
    @LIBS = []
  end
  libnames.each{|libname|
    if( !LIB_MAP[libname] )
      LIB_MAP[libname] = DL.dlopen(libname)
    end
    @LIBS.push(LIB_MAP[libname])
  }
end
            
Also aliased as: dllink
encode_argument_types(tys) click to toggle source
 
               # File dl/lib/dl/import.rb, line 187
def encode_argument_types(tys)
  init_types()
  encty = []
  enc = nil
  dec = nil
  tys.each_with_index{|ty,idx|
    ty,c1,c2 = @types.encode_argument_type(ty)
    if( !ty )
      raise(TypeError, "unsupported type: #{ty}")
    end
    encty.push(ty)
    if( enc )
      if( c1 )
        conv1 = enc
        enc = proc{|v| v = conv1.call(v); v[idx] = c1.call(v[idx]); v}
      end
    else
      if( c1 )
        enc = proc{|v| v[idx] = c1.call(v[idx]); v}
      end
    end
    if( dec )
      if( c2 )
        conv2 = dec
        dec = proc{|v| v = conv2.call(v); v[idx] = c2.call(v[idx]); v}
      end
    else
      if( c2 )
        dec = proc{|v| v[idx] = c2.call(v[idx]); v}
      end
    end
  }
  return [encty.join, enc, dec]
end
            
extern(proto) click to toggle source

example:

extern "int strlen(char*)"
 
               # File dl/lib/dl/import.rb, line 58
def extern(proto)
  func,ret,args = parse_cproto(proto)
  return import(func, ret, args)
end
            
import(name, rettype, argtypes = nil) click to toggle source

example:

import("get_length", "int", ["void*", "int"])
 
               # File dl/lib/dl/import.rb, line 133
def import(name, rettype, argtypes = nil)
  init_types()
  init_sym()

  rty,_,rdec = @types.encode_return_type(rettype)
  if( !rty )
    raise(TypeError, "unsupported type: #{rettype}")
  end
  ty,enc,dec = encode_argument_types(argtypes)
  symty = rty + ty

  sym = symbol(name, symty)

  mname = name.dup
  if( ?A <= mname[0] && mname[0] <= ?Z )
    mname[0,1] = mname[0,1].downcase
  end
  @SYM[mname] = [sym,rdec,enc,dec]
  
  module_eval [
    "def #{mname}(*args)",
    "  sym,rdec,enc,dec  = @SYM['#{mname}']",
    "  args = enc.call(args) if enc",
    if( $DEBUG )
      "  p \"[DL] call #{mname} with \#{args.inspect}\""
    else
      ""
    end,
    "  r,rs = sym.call(*args)",
    if( $DEBUG )
      "  p \"[DL] retval=\#{r.inspect} args=\#{rs.inspect}\""
    else
      ""
    end,
    "  r  = rdec.call(r) if rdec",
    "  rs = dec.call(rs) if dec",
    "  @retval = r",
    "  @args   = rs",
    "  return r",
    "end",
    "module_function :#{mname}",
  ].join("\n")

  return sym
end
            
init_sym() click to toggle source
 
               # File dl/lib/dl/import.rb, line 14
def init_sym()
  @SYM ||= {}
end
            
init_types() click to toggle source
 
               # File dl/lib/dl/import.rb, line 10
def init_types()
  @types ||= ::DL::Types.new
end
            
parse_cproto(proto) click to toggle source
 
               # File dl/lib/dl/import.rb, line 35
def parse_cproto(proto)
  proto = proto.gsub(/\s+/, " ").strip
  case proto
  when /^([\d\w\*_\s]+)\(([\d\w\*_\s\,\[\]]*)\)$/
    ret = $1
    args = $2.strip()
    ret = ret.split(/\s+/)
    args = args.split(/\s*,\s*/)
    func = ret.pop()
    if( func =~ /^\*/ )
      func.gsub!(/^\*+/,"")
      ret.push("*")
    end
    ret  = ret.join(" ")
    return [func, ret, args]
  else
    raise(RuntimeError,"can't parse the function prototype: #{proto}")
  end
end
            
struct(contents) click to toggle source
Alias for: define_struct
symbol(name, ty = nil) click to toggle source

example:

symbol "foo_value"
symbol "foo_func", "IIP"
 
               # File dl/lib/dl/import.rb, line 111
def symbol(name, ty = nil)
  sym = nil
  @LIBS.each{|lib|
    begin
      if( ty )
        sym = lib[name, ty]
      else
        sym = lib[name]
      end
    rescue
      next
    end
  }
  if( !sym )
    raise(RuntimeError, "can't find the symbol `#{name}'")
  end
  return sym
end
            
typealias(alias_type, ty1, enc1=nil, dec1=nil, ty2=nil, enc2=nil, dec2=nil) click to toggle source

example:

typealias("uint", "unsigned int")
 
               # File dl/lib/dl/import.rb, line 101
def typealias(alias_type, ty1, enc1=nil, dec1=nil, ty2=nil, enc2=nil, dec2=nil)
  init_types()
  @types.typealias(alias_type, ty1, enc1, dec1,
                               ty2||ty1, enc2, dec2)
end
            
union(contents) click to toggle source
Alias for: define_union