DL::Importable::Internal (Module)

In: dl/lib/dl/struct.rb
dl/lib/dl/import.rb

Methods

Public Instance methods

[Source]

# File dl/lib/dl/import.rb, line 23
      def [](name)
        return @SYM[name.to_s][0]
      end

[Source]

# File dl/lib/dl/import.rb, line 177
      def _args_
        return @args
      end

[Source]

# File dl/lib/dl/import.rb, line 181
      def _retval_
        return @retval
      end

example:

  callback "int method_name(int, char*)"

[Source]

# File dl/lib/dl/import.rb, line 71
      def callback(proto)
        func,ret,args = parse_cproto(proto)

        init_types()
        init_sym()

        rty,renc,rdec = @types.encode_type(ret)
        ty,enc,dec = encode_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",
          "  @retval = r",
          "  @args   = rs",
          "  @retval",
          "}",
        ].join("\n"))

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

        return sym
      end

[Source]

# File dl/lib/dl/struct.rb, line 9
      def define_struct(contents)
        init_types()
        Struct.new(@types, contents)
      end

[Source]

# File dl/lib/dl/struct.rb, line 15
      def define_union(contents)
        init_types()
        Union.new(@types, contents)
      end
dllink(*libnames)

Alias for dlload

[Source]

# File dl/lib/dl/import.rb, line 27
      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

[Source]

# File dl/lib/dl/import.rb, line 185
      def encode_types(tys)
        init_types()
        encty = []
        enc = nil
        dec = nil
        tys.each_with_index{|ty,idx|
          ty,c1,c2,_,_ = @types.encode_type(ty)
          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

example:

  extern "int strlen(char*)"

[Source]

# File dl/lib/dl/import.rb, line 63
      def extern(proto)
        func,ret,args = parse_cproto(proto)
        return import(func, ret, args)
      end

example:

  import("get_length", "int", ["void*", "int"])

[Source]

# File dl/lib/dl/import.rb, line 134
      def import(name, rettype, argtypes = nil)
        init_types()
        init_sym()

        rty,_,rdec = @types.encode_type(rettype)
        ty,enc,dec = encode_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 @retval",
          "end",
          "module_function :#{mname}",
        ].join("\n")

        return sym
      end

[Source]

# File dl/lib/dl/import.rb, line 17
      def init_sym()
        if( !@SYM )
          @SYM = {}
        end
      end

[Source]

# File dl/lib/dl/import.rb, line 11
      def init_types()
        if( !@types )
          @types = ::DL::Types.new
        end
      end

[Source]

# File dl/lib/dl/import.rb, line 40
      def parse_cproto(proto)
        proto = proto.gsub(/\s+/, " ").strip
        case proto
        when /^([\d\w\*_\s]+)\(([\d\w\*_\s\,\[\]]*)\)$/
          ret = $1
          args = $2
          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)

Alias for define_struct

example:

 symbol "foo_value"
 symbol "foo_func", "IIP"

[Source]

# File dl/lib/dl/import.rb, line 112
      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

example:

 typealias("uint", "unsigned int")

[Source]

# File dl/lib/dl/import.rb, line 103
      def typealias(*args)
        init_types()
        @types.typealias(*args)
      end
union(contents)

Alias for define_union

[Validate]