Extended maintenance of Ruby versions 1.8.7 and 1.9.2 will end on July 31, 2014. Read more

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

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