Top Level Namespace

Includes:
Kernel32

Defined Under Namespace

Modules: DL, Kernel32, LIBC, LIBTest, NTFS Classes: Person, 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,
  },
}
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 '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 '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 '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 '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



8
9
10
11
12
13
14
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
# File 'mkcallback.rb', line 8

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



8
9
10
11
12
# File 'mkcbtable.rb', line 8

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 '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



8
9
10
# File 'mkcall.rb', line 8

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

#output_args(types) ⇒ Object



12
13
14
15
16
# File 'mkcall.rb', line 12

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



18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'mkcall.rb', line 18

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



33
34
35
36
37
38
39
40
41
42
43
44
# File 'mkcall.rb', line 33

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

#rec_output(types = [VOID]) ⇒ Object



46
47
48
49
50
51
52
53
54
55
# File 'mkcall.rb', line 46

def rec_output(types = [VOID])
  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 'type.rb', line 84

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

#tpush(t, x) ⇒ Object



80
81
82
# File 'type.rb', line 80

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

#types2ctypes(types) ⇒ Object



109
110
111
112
113
114
115
# File '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 'type.rb', line 88

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