Top Level Namespace

Includes:
Kernel32

Defined Under Namespace

Modules: DL, Kernel32, LIBC, LIBTest, NTFS, RubySL Classes: Array, IO, Person, String, Win32API

Constant Summary collapse

DLTYPE =

example:

DLTYPE[INT][:rb2c]["arg0"] => "NUM2INT(arg0)"
DLTYPE[DOUBLE][:c2rb]["r"] => "rb_float_new(r)"
{
  VOID  = 0x00 => {
    :name => 'VOID',
    :rb2c => nil,
    :c2rb => nil,
    :ctype => "void",
    :stmem => "v",
    :sym => true,
    :cb => true,
  },
  CHAR  = 0x01 => {
    :name => 'CHAR',
    :rb2c => proc{|x| "NUM2CHR(#{x})"},
    :c2rb => proc{|x| "CHR2FIX(#{x})"},
    :ctype => "char",
    :stmem => "c",
    :sym => false,
    :cb => false,
  },
  SHORT = 0x02 => {
    :name => 'SHORT',
    :rb2c => proc{|x| "FIX2INT(#{x})"},
    :c2rb => proc{|x| "INT2FIX(#{x})"},
    :ctype => "short",
    :stmem => "h",
    :sym => false,
    :cb => false,
  },
  INT   = 0x03 => {
    :name => 'INT',
    :rb2c => proc{|x| "NUM2INT(#{x})"},
    :c2rb => proc{|x| "INT2NUM(#{x})"},
    :ctype => "int",
    :stmem => "i",
    :sym => true,
    :cb => false,
  },
  LONG  = 0x04 => {
    :name => 'LONG',
    :rb2c => proc{|x| "NUM2INT(#{x})"},
    :c2rb => proc{|x| "INT2NUM(#{x})"},
    :ctype => "long",
    :stmem => "l",
    :sym => true,
    :cb => true,
  },
  FLOAT = 0x05 => {
    :name => 'FLOAT',
    :rb2c => proc{|x| "(float)(RFLOAT(#{x})->value)"},
    :c2rb => proc{|x| "rb_float_new((double)#{x})"},
    :ctype => "float",
    :stmem => "f",
    :sym => false,
    :cb => false,
  },
  DOUBLE = 0x06 => {
    :name => 'DOUBLE',
    :rb2c => proc{|x| "RFLOAT(#{x})->value"},
    :c2rb => proc{|x| "rb_float_new(#{x})"},
    :ctype => "double",
    :stmem => "d",
    :sym => true,
    :cb => true,
  },
  VOIDP = 0x07 => {
    :name => 'VOIDP',
    :rb2c => proc{|x| "rb_dlptr2cptr(#{x})"},
    :c2rb => proc{|x| "rb_dlptr_new(#{x},sizeof(void*),0)"},
    :ctype => "void *",
    :stmem => "p",
    :sym => true,
    :cb => true,
  },
}
OUTPUT =
STDOUT
SO_LIBS =
["dl.so"]
User32 =
DL.dlopen("user32")
MB_OK =
0
MB_OKCANCEL =
1
LIBNAME =

Give a name of dynamic loadable library

ARGV[0] || "libsample.so"

Constants included from DL::Importable

DL::Importable::LIB_MAP

Instance Method Summary collapse

Methods included from DL::Importable::Internal

#[], #_args_, #_retval_, #callback, #define_struct, #define_union, #dlload, #encode_argument_types, #extern, #import, #init_sym, #init_types, #parse_cproto, #symbol, #typealias

Instance Method Details

#assert(label, ty, *conds) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'ext/rubysl/dl/test/test.rb', line 9

def assert(label, ty, *conds)
  $TOTAL += 1
  cond = !conds.include?(false)
  if( cond )
    printf("succeed in `#{label}'\n")
  else
    $FAIL += 1
    case ty
    when :may
      printf("fail in `#{label}' ... expected\n")
    when :must
      printf("fail in `#{label}' ... unexpected\n")
    when :raise
      raise(RuntimeError, "fail in `#{label}'")
    end
  end
end

#debug(*xs) ⇒ Object



27
28
29
30
31
32
33
# File 'ext/rubysl/dl/test/test.rb', line 27

def debug(*xs)
  if( $DEBUG )
    xs.each{|x|
      p x
    }
  end
end

#find(dir, match = /./) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'ext/rubysl/dl/install.rb', line 13

def find(dir, match = /./)
  Dir.chdir(dir)
  files = []
  Dir.new(".").each{|file|
    if( file != "." && file != ".." )
      case File.ftype(file)
      when "file"
	if( file =~ match )
	  files.push(File.join(dir,file))
	end
      when "directory"
	files += find(file, match).collect{|f| File.join(dir,f)}
      end
    end
  }
  Dir.chdir("..")
  return files
end

#installObject



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'ext/rubysl/dl/install.rb', line 32

def install()
  rb_files = find(File.join(".","lib"), /.rb$/)

  SO_LIBS.each{|f|
    File.makedirs($rubylibdir, "#{$archdir}")
    File.install(f, File.join($archdir,f), 0555, true)
  }

  rb_files.each{|f|
    origfile = f
    instfile = File.join($rubylibdir, origfile.sub("./lib/",""))
    instdir  = File.dirname(instfile)
    File.makedirs(instdir)
    File.install(origfile, instfile, 0644, true)
  }
end

#mkfunc(rettype, fnum, argc) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'ext/rubysl/dl/mkcallback.rb', line 15

def mkfunc(rettype, fnum, argc)
  args = (0..(argc-1)).collect{|i| "long arg#{i}"}.join(", ")

  subst_code = (0..(argc-1)).collect{|i|
    "  buff[#{i.to_s}] = arg#{i.to_s};"
  }.join("\n")

  ret_code =
    if( DLTYPE[rettype][:c2rb] )
      "  return #{DLTYPE[rettype][:rb2c]['retval']};"
    else
      "  /* no return value */"
    end

  code = [
    "static #{DLTYPE[rettype][:ctype]}",
    "rb_dl_callback_func_#{rettype.to_s}_#{fnum.to_s}(#{args})",
    "{",
    "  VALUE retval, proto, proc, obj;",
    "  VALUE argv[#{argc.to_s}];",
    "  int  argc;",
    "  long buff[#{argc.to_s}];",
    "",
    subst_code,
    "",
    "  obj = rb_hash_aref(DLFuncTable, rb_assoc_new(INT2NUM(#{rettype.to_s}),INT2NUM(#{fnum.to_s})));",
    "  if(NIL_P(obj))",
    "    rb_raise(rb_eDLError, \"callback function does not exist in DL::FuncTable\");",
    "  Check_Type(obj, T_ARRAY);",
    "  proto = rb_ary_entry(obj, 0);",
    "  proc  = rb_ary_entry(obj, 1);",
    "  Check_Type(proto, T_STRING);",
    "  if( RSTRING(proto)->len >= #{argc.to_s} )",
    "    rb_raise(rb_eArgError, \"too many arguments\");",
    "  rb_dl_scan_callback_args(buff, RSTRING(proto)->ptr, &argc, argv);",
    "  retval = rb_funcall2(proc, id_call, argc, argv);",
    "",
    ret_code,
    "}",
  ].join("\n")

  return code
end

#mktable(rettype, fnum, argc) ⇒ Object



15
16
17
18
19
# File 'ext/rubysl/dl/mkcbtable.rb', line 15

def mktable(rettype, fnum, argc)
  code =
    "rb_dl_callback_table[#{rettype}][#{fnum}] = &rb_dl_callback_func_#{rettype.to_s}_#{fnum};"
  return code
end

#num2types(num) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
# File 'ext/rubysl/dl/type.rb', line 97

def num2types(num)
  ts = []
  i  = 0
  t = tget(num,i)
  while( (t != VOID && i > 0) || (i == 0) )
    ts.push(DLTYPE[t][:ctype])
    i += 1
    t = tget(num,i)
  end
  ts
end

#output_arg(x, i) ⇒ Object



15
16
17
# File 'ext/rubysl/dl/mkcall.rb', line 15

def output_arg(x,i)
  "args[#{i}].#{DLTYPE[x][:stmem]}"
end

#output_args(types) ⇒ Object



19
20
21
22
23
# File 'ext/rubysl/dl/mkcall.rb', line 19

def output_args(types)
  t = []
  types[1..-1].each_with_index{|x,i| t.push(output_arg(x,i))}
  t.join(",")
end

#output_callfunc(types) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'ext/rubysl/dl/mkcall.rb', line 25

def output_callfunc(types)
  t = types[0]
  stmem = DLTYPE[t][:stmem]
  ctypes = types2ctypes(types)
  if( t == VOID )
    callstm = "(*f)(#{output_args(types)})"
  else
    callstm = "ret.#{stmem} = (*f)(#{output_args(types)})"
  end
  [ "{",
    "#{ctypes[0]} (*f)(#{ctypes[1..-1].join(',')}) = func;",
    "#{callstm};",
    "}"].join(" ")
end

#output_case(types) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
# File 'ext/rubysl/dl/mkcall.rb', line 40

def output_case(types)
  num = types2num(types)
  callfunc_stm = output_callfunc(types)
<<EOF
  case #{num}:
#ifdef DEBUG
    OUTPUT.printf("#{callfunc_stm}\\n");
#endif
    #{callfunc_stm};
    break;
EOF
end

#rec_output(types = [VOID]) ⇒ Object



53
54
55
56
57
58
59
60
61
62
# File 'ext/rubysl/dl/mkcall.rb', line 53

def rec_output(types = [VOID])
  OUTPUT.print output_case(types)
  if( types.length <= MAX_ARG )
    DLTYPE.keys.sort.each{|t|
      if( t != VOID && DLTYPE[t][:sym] )
	rec_output(types + [t])
      end
    }
  end
end

#tget(t, i) ⇒ Object



84
85
86
# File 'ext/rubysl/dl/type.rb', line 84

def tget(t, i)
  (t & (0x07 << (i * 3))) >> (i * 3)
end

#tpush(t, x) ⇒ Object



80
81
82
# File 'ext/rubysl/dl/type.rb', line 80

def tpush(t, x)
  (t << 3)|x
end

#types2ctypes(types) ⇒ Object



109
110
111
112
113
114
115
# File 'ext/rubysl/dl/type.rb', line 109

def types2ctypes(types)
  res = []
  types.each{|t|
    res.push(DLTYPE[t][:ctype])
  }
  res
end

#types2num(types) ⇒ Object



88
89
90
91
92
93
94
95
# File 'ext/rubysl/dl/type.rb', line 88

def types2num(types)
  res = 0x00
  r = types.reverse
  r.each{|t|
    res = tpush(res,t)
  }
  res
end