mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* ext/dl: change the callback mechanism.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2532 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
d5ceb6ef82
commit
2d5b7f7365
8 changed files with 214 additions and 240 deletions
|
@ -1,3 +1,7 @@
|
|||
Sun Jun 9 17:40:41 2002 Takaaki Tateishi <ttate@kt.jaist.ac.jp>
|
||||
|
||||
* ext/dl: change the callback mechanism.
|
||||
|
||||
Thu Jun 6 19:50:39 2002 KONISHI Hiromasa <H_Konishi@ruby-lang.org>
|
||||
|
||||
* sample/biorhythm.rb (getPosiiton,etc)
|
||||
|
|
250
ext/dl/dl.c
250
ext/dl/dl.c
|
@ -11,9 +11,95 @@ VALUE rb_eDLError;
|
|||
VALUE rb_eDLTypeError;
|
||||
|
||||
static VALUE DLFuncTable;
|
||||
static void *rb_dl_func_table[MAX_CALLBACK_TYPE][MAX_CALLBACK];
|
||||
static void *rb_dl_callback_table[CALLBACK_TYPES][MAX_CALLBACK];
|
||||
static ID id_call;
|
||||
|
||||
static int
|
||||
rb_dl_scan_callback_args(long stack[], const char *proto,
|
||||
int *argc, VALUE (*argv)[])
|
||||
{
|
||||
int i;
|
||||
long *sp;
|
||||
VALUE val;
|
||||
|
||||
sp = stack;
|
||||
for( i=1; proto[i]; i++ ){
|
||||
switch( proto[i] ){
|
||||
case 'C':
|
||||
{
|
||||
char v;
|
||||
memcpy(&v, sp, sizeof(long));
|
||||
sp++;
|
||||
val = INT2NUM(v);
|
||||
}
|
||||
break;
|
||||
case 'H':
|
||||
{
|
||||
short v;
|
||||
memcpy(&v, sp, sizeof(long));
|
||||
sp++;
|
||||
val = INT2NUM(v);
|
||||
}
|
||||
break;
|
||||
case 'I':
|
||||
{
|
||||
int v;
|
||||
memcpy(&v, sp, sizeof(long));
|
||||
sp++;
|
||||
val = INT2NUM(v);
|
||||
}
|
||||
break;
|
||||
case 'L':
|
||||
{
|
||||
long v;
|
||||
memcpy(&v, sp, sizeof(long));
|
||||
sp++;
|
||||
val = INT2NUM(v);
|
||||
}
|
||||
break;
|
||||
case 'F':
|
||||
{
|
||||
float v;
|
||||
memcpy(&v, sp, sizeof(float));
|
||||
sp += sizeof(float)/sizeof(long);
|
||||
val = rb_float_new(v);
|
||||
}
|
||||
break;
|
||||
case 'D':
|
||||
{
|
||||
double v;
|
||||
memcpy(&v, sp, sizeof(double));
|
||||
sp += sizeof(double)/sizeof(long);
|
||||
val = rb_float_new(v);
|
||||
}
|
||||
break;
|
||||
case 'P':
|
||||
{
|
||||
void *v;
|
||||
memcpy(&v, sp, sizeof(void*));
|
||||
sp++;
|
||||
val = rb_dlptr_new(v, 0, 0);
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
{
|
||||
char *v;
|
||||
memcpy(&v, sp, sizeof(void*));
|
||||
sp++;
|
||||
val = rb_tainted_str_new2(v);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
rb_raise(rb_eDLTypeError, "unsupported type `%c'", proto[i]);
|
||||
break;
|
||||
}
|
||||
(*argv)[i-1] = val;
|
||||
}
|
||||
*argc = (i - 1);
|
||||
|
||||
return (*argc);
|
||||
}
|
||||
|
||||
#include "callback.func"
|
||||
|
||||
static void
|
||||
|
@ -476,121 +562,88 @@ rb_dl_sizeof(VALUE self, VALUE str)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_dl_callback_type(VALUE *str)
|
||||
rb_dl_callback(int argc, VALUE argv[], VALUE self)
|
||||
{
|
||||
char *type;
|
||||
int len;
|
||||
int i;
|
||||
long ftype;
|
||||
VALUE type, proc;
|
||||
int rettype, entry, i;
|
||||
char fname[127];
|
||||
|
||||
ftype = 0;
|
||||
type = StringValuePtr(*str);
|
||||
len = RSTRING(*str)->len;
|
||||
|
||||
if( len - 1 > MAX_CBARG ){
|
||||
rb_raise(rb_eDLError, "maximum number of the argument is %d.", MAX_CBARG);
|
||||
};
|
||||
|
||||
for( i = len - 1; i > 0; i-- ){
|
||||
switch( type[i] ){
|
||||
case 'P':
|
||||
CBPUSH_P(ftype);
|
||||
break;
|
||||
case 'I':
|
||||
CBPUSH_I(ftype);
|
||||
break;
|
||||
case 'L':
|
||||
CBPUSH_L(ftype);
|
||||
break;
|
||||
case 'F':
|
||||
CBPUSH_F(ftype);
|
||||
break;
|
||||
case 'D':
|
||||
CBPUSH_D(ftype);
|
||||
default:
|
||||
rb_raise(rb_eDLError, "unsupported type `%c'", type[i]);
|
||||
break;
|
||||
};
|
||||
proc = Qnil;
|
||||
switch( rb_scan_args(argc, argv, "11", &type, &proc) ){
|
||||
case 1:
|
||||
if( rb_block_given_p() ){
|
||||
proc = rb_f_lambda();
|
||||
}
|
||||
else{
|
||||
proc = Qnil;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch( type[0] ){
|
||||
Check_Type(type, T_STRING);
|
||||
switch( STR2CSTR(type)[0] ){
|
||||
case '0':
|
||||
CBPUSH_0(ftype);
|
||||
rettype = 0x00;
|
||||
break;
|
||||
case 'P':
|
||||
CBPUSH_P(ftype);
|
||||
case 'C':
|
||||
rettype = 0x01;
|
||||
break;
|
||||
case 'H':
|
||||
rettype = 0x02;
|
||||
break;
|
||||
case 'I':
|
||||
CBPUSH_I(ftype);
|
||||
rettype = 0x03;
|
||||
break;
|
||||
case 'L':
|
||||
CBPUSH_L(ftype);
|
||||
rettype = 0x04;
|
||||
break;
|
||||
case 'F':
|
||||
CBPUSH_F(ftype);
|
||||
rettype = 0x05;
|
||||
break;
|
||||
case 'D':
|
||||
CBPUSH_D(ftype);
|
||||
rettype = 0x06;
|
||||
break;
|
||||
case 'P':
|
||||
rettype = 0x07;
|
||||
break;
|
||||
default:
|
||||
rb_raise(rb_eDLError, "unsupported type `%c'", type[i]);
|
||||
break;
|
||||
};
|
||||
|
||||
return INT2NUM(ftype);
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_dl_set_callback(int argc, VALUE argv[], VALUE self)
|
||||
{
|
||||
VALUE types, num, proc;
|
||||
VALUE key;
|
||||
VALUE entry;
|
||||
void *func;
|
||||
|
||||
char func_name[1024];
|
||||
extern dln_sym();
|
||||
|
||||
switch( rb_scan_args(argc, argv, "21", &types, &num, &proc) ){
|
||||
case 2:
|
||||
proc = rb_f_lambda();
|
||||
break;
|
||||
case 3:
|
||||
break;
|
||||
default:
|
||||
rb_bug("rb_dl_set_callback");
|
||||
};
|
||||
|
||||
key = rb_dl_callback_type(&types);
|
||||
entry = rb_hash_aref(DLFuncTable, key);
|
||||
if( entry == Qnil ){
|
||||
entry = rb_hash_new();
|
||||
rb_hash_aset(DLFuncTable, key, entry);
|
||||
};
|
||||
|
||||
func = rb_dl_func_table[NUM2INT(key)][NUM2INT(num)];
|
||||
if( func ){
|
||||
rb_hash_aset(entry, num, proc);
|
||||
snprintf(func_name, 1023, "rb_dl_func%d_%d", NUM2INT(key), NUM2INT(num));
|
||||
return rb_dlsym_new(func, func_name, RSTRING(types)->ptr);
|
||||
rb_raise(rb_eDLTypeError, "unsupported type `%s'", STR2CSTR(rettype));
|
||||
}
|
||||
else{
|
||||
return Qnil;
|
||||
};
|
||||
|
||||
entry = -1;
|
||||
for( i=0; i < MAX_CALLBACK; i++ ){
|
||||
if( rb_hash_aref(DLFuncTable, rb_assoc_new(INT2NUM(rettype), INT2NUM(i))) == Qnil ){
|
||||
entry = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( entry < 0 ){
|
||||
rb_raise(rb_eDLError, "too many callbacks are defined.");
|
||||
}
|
||||
|
||||
rb_hash_aset(DLFuncTable,
|
||||
rb_assoc_new(INT2NUM(rettype),INT2NUM(entry)),
|
||||
rb_assoc_new(type,proc));
|
||||
sprintf(fname, "rb_dl_callback_func_%d_%d", rettype, entry);
|
||||
return rb_dlsym_new(rb_dl_callback_table[rettype][entry], fname, STR2CSTR(type));
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_dl_get_callback(VALUE self, VALUE types, VALUE num)
|
||||
static VALUE
|
||||
rb_dl_remove_callback(VALUE mod, VALUE sym)
|
||||
{
|
||||
VALUE key;
|
||||
VALUE entry;
|
||||
freefunc_t f = rb_dlsym2csym(sym);
|
||||
int i, j;
|
||||
|
||||
key = rb_dl_callback_type(&types);
|
||||
entry = rb_hash_aref(DLFuncTable, key);
|
||||
if( entry == Qnil ){
|
||||
return Qnil;
|
||||
};
|
||||
return rb_hash_aref(entry, num);
|
||||
for( i=0; i < CALLBACK_TYPES; i++ ){
|
||||
for( j=0; j < MAX_CALLBACK; j++ ){
|
||||
if( rb_dl_callback_table[i][j] == f ){
|
||||
rb_hash_aset(DLFuncTable, rb_assoc_new(INT2NUM(i),INT2NUM(j)),Qnil);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -627,13 +680,12 @@ Init_dl()
|
|||
rb_define_const(rb_mDL, "MINOR_VERSION", INT2NUM(DL_MINOR_VERSION));
|
||||
rb_define_const(rb_mDL, "PATCH_VERSION", INT2NUM(DL_PATCH_VERSION));
|
||||
rb_define_const(rb_mDL, "MAX_ARG", INT2NUM(MAX_ARG));
|
||||
rb_define_const(rb_mDL, "MAX_CBARG", INT2NUM(MAX_CBARG));
|
||||
rb_define_const(rb_mDL, "MAX_CBENT", INT2NUM(MAX_CBENT));
|
||||
rb_define_const(rb_mDL, "DLSTACK", rb_tainted_str_new2(DLSTACK_METHOD));
|
||||
|
||||
rb_define_module_function(rb_mDL, "dlopen", rb_dl_dlopen, -1);
|
||||
rb_define_module_function(rb_mDL, "set_callback", rb_dl_set_callback, -1);
|
||||
rb_define_module_function(rb_mDL, "get_callback", rb_dl_get_callback, 2);
|
||||
rb_define_module_function(rb_mDL, "callback", rb_dl_callback, -1);
|
||||
rb_define_module_function(rb_mDL, "define_callback", rb_dl_callback, -1);
|
||||
rb_define_module_function(rb_mDL, "remove_callback", rb_dl_remove_callback, 1);
|
||||
rb_define_module_function(rb_mDL, "malloc", rb_dl_malloc, 1);
|
||||
rb_define_module_function(rb_mDL, "strdup", rb_dl_strdup, 1);
|
||||
rb_define_module_function(rb_mDL, "sizeof", rb_dl_sizeof, 1);
|
||||
|
|
|
@ -52,9 +52,9 @@ struct and union which are defined in "dl/struct.rb" as follows:
|
|||
"long tv_uses",
|
||||
]
|
||||
end
|
||||
val = LIBC::Timeval.alloc # allocate the memory.
|
||||
val = LIBC::Timeval.malloc # allocate the memory.
|
||||
|
||||
The above example uses LIBC::Timeval.alloc, since we use LIBC::Timeval.new(ptr)
|
||||
The above example uses LIBC::Timeval.malloc, since we use LIBC::Timeval.new(ptr)
|
||||
to wrap the given PtrData object which is, for example, created by DL::malloc().
|
||||
DL::malloc() is a function to allocate a memory by using the C library function
|
||||
malloc().
|
||||
|
@ -244,10 +244,10 @@ the type of each argument.
|
|||
p : a mutable object (void *)
|
||||
0 : void function (this must be a first character of the prototype)
|
||||
|
||||
the cbtype consists of type specifiers 0, I, L, D and P.
|
||||
the cbtype consists of type specifiers 0, C, I, H, L, F, D, S and P.
|
||||
for example:
|
||||
|
||||
DL.set_callback('IPP',0){|ptr1,ptr2|
|
||||
DL.callback('IPP'){|ptr1,ptr2|
|
||||
str1 = ptr1.ptr.to_s
|
||||
str2 = ptr2.ptr.to_s
|
||||
return str1 <=> str2
|
||||
|
|
|
@ -11,10 +11,8 @@ if( ARGV.include?("--help") )
|
|||
--with-type-char strictly use type 'char'
|
||||
--with-type-short strictly use type 'short'
|
||||
--with-type-float strictly use type 'float'
|
||||
--with-args=<max_arg>,<max_cbarg>,<max_cbent>
|
||||
<max_arg>: maximum number of arguments of the function
|
||||
<max_cbarg>: maximum number of arguments of the callback
|
||||
<max_cbent>: maximum number of callback entries
|
||||
--with-args=<max_arg>
|
||||
--with-callback=<max_callback>
|
||||
--enable-asm use the embedded assembler for passing arguments.
|
||||
(this option is available for i386 machine now.)
|
||||
--enable-dlstack use a stack emulation for constructing function call.
|
||||
|
@ -58,8 +56,6 @@ $with_type_int &= DLTYPE[INT][:sym]
|
|||
$with_type_float &= DLTYPE[FLOAT][:sym]
|
||||
$with_type_voidp &= DLTYPE[VOIDP][:sym]
|
||||
|
||||
$with_cbtype_voidp = DLTYPE[VOIDP][:cb]
|
||||
|
||||
$with_type_char = enable_config("type-char", $with_type_char)
|
||||
$with_type_short = enable_config("type-short", $with_type_short)
|
||||
$with_type_float = enable_config("type-float", $with_type_float)
|
||||
|
@ -68,7 +64,7 @@ $with_asm = enable_config("asm", $with_asm)
|
|||
$with_dlstack = enable_config("dlstack", $with_dlstack)
|
||||
|
||||
args = with_config("args")
|
||||
max_arg = max_cbarg = max_cbent = nil
|
||||
max_arg = nil
|
||||
if( $with_asm || $with_dlstack )
|
||||
$with_type_char = true
|
||||
$with_type_short = true
|
||||
|
@ -76,31 +72,20 @@ if( $with_asm || $with_dlstack )
|
|||
max_arg = 0
|
||||
end
|
||||
if( args )
|
||||
max_arg,max_cbarg,max_cbent = args.split(",").collect{|c| c.to_i}
|
||||
if( !(max_arg && max_cbarg && max_cbent) )
|
||||
print("--with-args=<max_arg>,<max_cbarg>,<max_cbent>\n")
|
||||
max_arg = args.to_i
|
||||
if( !max_arg )
|
||||
print("--with-args=<max_arg>\n")
|
||||
exit(1)
|
||||
end
|
||||
end
|
||||
max_arg ||= 6
|
||||
max_cbarg ||= 3
|
||||
max_cbent ||= 3
|
||||
|
||||
max_callback_type = types2num(DLTYPE.keys.sort[-1,1] * (max_cbarg + 1)) + 1
|
||||
max_callback = max_cbent
|
||||
|
||||
#m = [1].pack("i")
|
||||
#c,cs = m.unpack("c")
|
||||
#bigendian = (c == 0)
|
||||
#print("bigendian ... #{bigendian ? 'true' : 'false'}\n")
|
||||
max_callback = with_config("callback","10").to_i
|
||||
callback_types = DLTYPE.keys.length
|
||||
|
||||
|
||||
$dlconfig_h = <<EOF
|
||||
#define MAX_ARG #{max_arg}
|
||||
#define MAX_CBARG #{max_cbarg}
|
||||
#define MAX_CBENT #{max_cbent}
|
||||
#define MAX_CALLBACK_TYPE #{max_callback_type}
|
||||
#define MAX_CALLBACK #{max_callback}
|
||||
#define MAX_ARG #{max_arg}
|
||||
EOF
|
||||
|
||||
def dlc_define(const)
|
||||
|
@ -109,6 +94,8 @@ def dlc_define(const)
|
|||
"#endif\n"
|
||||
end
|
||||
|
||||
$dlconfig_h << "#define MAX_CALLBACK #{max_callback}\n"
|
||||
$dlconfig_h << "#define CALLBACK_TYPES #{callback_types}\n"
|
||||
if( $with_dlstack )
|
||||
$dlconfig_h << "#define USE_DLSTACK\n"
|
||||
else
|
||||
|
@ -137,15 +124,6 @@ end
|
|||
if( $with_type_voidp )
|
||||
$dlconfig_h << "#define WITH_TYPE_VOIDP\n"
|
||||
end
|
||||
if( $with_cbtype_voidp )
|
||||
$dlconfig_h << "#define WITH_CBTYPE_VOIDP\n"
|
||||
end
|
||||
#if( bigendian )
|
||||
# $dlconfig_h << "#define BIGENDIAN"
|
||||
#else
|
||||
# $dlconfig_h << "#define LITTLEENDIAN"
|
||||
#end
|
||||
|
||||
|
||||
if( have_header("dlfcn.h") )
|
||||
dlc_define("HAVE_DLFCN_H")
|
||||
|
@ -182,8 +160,8 @@ EOF
|
|||
|
||||
File.update("dlconfig.rb", <<EOF)
|
||||
MAX_ARG = #{max_arg}
|
||||
MAX_CBARG = #{max_cbarg}
|
||||
MAX_CBENT = #{max_cbent}
|
||||
MAX_CALLBACK = #{max_callback}
|
||||
CALLBACK_TYPES = #{callback_types}
|
||||
DLTYPE[CHAR][:sym] = #{$with_type_char}
|
||||
DLTYPE[SHORT][:sym] = #{$with_type_short}
|
||||
DLTYPE[INT][:sym] = #{$with_type_int}
|
||||
|
|
|
@ -5,79 +5,46 @@ $:.unshift File.dirname(__FILE__)
|
|||
require 'type'
|
||||
require 'dlconfig'
|
||||
|
||||
$int_eq_long = try_run(<<EOF)
|
||||
int main() {
|
||||
return sizeof(int) == sizeof(long) ? 0 : 1;
|
||||
}
|
||||
EOF
|
||||
def mkfunc(rettype, fnum, argc)
|
||||
args = (0..(argc-1)).collect{|i| "long arg#{i}"}.join(", ")
|
||||
|
||||
def func_arg(x,i)
|
||||
ctype = DLTYPE[x][:ctype]
|
||||
"#{ctype} arg#{i}"
|
||||
end
|
||||
subst_code = (0..(argc-1)).collect{|i|
|
||||
" buff[#{i.to_s}] = arg#{i.to_s};"
|
||||
}.join("\n")
|
||||
|
||||
def func_args(types)
|
||||
t = []
|
||||
types[1..-1].each_with_index{|x,i| t.push(func_arg(x,i))}
|
||||
t.join(", ")
|
||||
end
|
||||
ret_code =
|
||||
if( DLTYPE[rettype][:c2rb] )
|
||||
" return #{DLTYPE[rettype][:rb2c][\"retval\"]};"
|
||||
else
|
||||
" /* no return value */"
|
||||
end
|
||||
|
||||
def funcall_args(types)
|
||||
num = types.length - 1
|
||||
if( num > 0 )
|
||||
t = []
|
||||
types[1..-1].each_with_index{|x,i| t.push(DLTYPE[x][:c2rb].call("arg#{i}"))}
|
||||
return num.to_s + ", " + t.join(", ")
|
||||
else
|
||||
return num.to_s
|
||||
end
|
||||
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})));",
|
||||
" proto = rb_ary_entry(obj, 0);",
|
||||
" proc = rb_ary_entry(obj, 1);",
|
||||
" rb_dl_scan_callback_args(buff, STR2CSTR(proto), &argc, &argv);",
|
||||
" retval = rb_funcall2(proc, id_call, argc, argv);",
|
||||
"",
|
||||
ret_code,
|
||||
"}",
|
||||
].join("\n")
|
||||
|
||||
def output_func(types, n = 0)
|
||||
func_name = "rb_dl_func#{types2num(types)}_#{n}"
|
||||
code =
|
||||
"#{func_name}(#{func_args(types)}) /* #{types2ctypes(types).inspect} */\n" +
|
||||
"{\n" +
|
||||
" VALUE val, obj;\n" +
|
||||
"#ifdef DEBUG\n" +
|
||||
" printf(\"#{func_name}()\\n\");\n" +
|
||||
"#endif\n" +
|
||||
" obj = rb_hash_aref(DLFuncTable, INT2NUM(#{types2num(types)}));\n" +
|
||||
" obj = rb_hash_aref(obj,INT2NUM(#{n}));\n" +
|
||||
" val = rb_funcall(obj, id_call,\n" +
|
||||
" #{funcall_args(types)});\n"
|
||||
|
||||
rtype = DLTYPE[types[0]][:ctype]
|
||||
rcode = DLTYPE[types[0]][:rb2c]
|
||||
if( rcode )
|
||||
code += " return #{rcode.call('val')};\n"
|
||||
end
|
||||
|
||||
code =
|
||||
rtype + "\n" +
|
||||
code +
|
||||
"}\n\n"
|
||||
if( n < MAX_CBENT - 1)
|
||||
return code + output_func(types, n+1)
|
||||
else
|
||||
return code
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def rec_output(types = [VOID])
|
||||
print output_func(types)
|
||||
if( types.length <= MAX_CBARG )
|
||||
DLTYPE.keys.sort.each{|t|
|
||||
if( t != VOID && DLTYPE[t][:cb] )
|
||||
rec_output(types + [t])
|
||||
end
|
||||
}
|
||||
end
|
||||
return code
|
||||
end
|
||||
|
||||
DLTYPE.keys.sort.each{|t|
|
||||
if( DLTYPE[t][:cb] )
|
||||
rec_output([t])
|
||||
for n in 0..(MAX_CALLBACK - 1)
|
||||
print(mkfunc(t, n, 15), "\n\n")
|
||||
end
|
||||
}
|
||||
|
|
|
@ -5,38 +5,14 @@ $:.unshift File.dirname(__FILE__)
|
|||
require 'type'
|
||||
require 'dlconfig'
|
||||
|
||||
$int_eq_long = try_run(<<EOF)
|
||||
int main() {
|
||||
return sizeof(int) == sizeof(long) ? 0 : 1;
|
||||
}
|
||||
EOF
|
||||
|
||||
def output_func(types, n = 0)
|
||||
def mktable(rettype, fnum, argc)
|
||||
code =
|
||||
"/* #{types2ctypes(types).inspect} */\n" +
|
||||
"rb_dl_func_table[#{types2num(types)}][#{n}] " +
|
||||
"= rb_dl_func#{types2num(types)}_#{n};\n"
|
||||
if( n < MAX_CBENT - 1)
|
||||
return code + output_func(types, n+1)
|
||||
else
|
||||
return code
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def rec_output(types = [VOID])
|
||||
print output_func(types)
|
||||
if( types.length <= MAX_CBARG )
|
||||
DLTYPE.keys.sort.each{|t|
|
||||
if( t != VOID && DLTYPE[t][:cb] )
|
||||
rec_output(types + [t])
|
||||
end
|
||||
}
|
||||
end
|
||||
"rb_dl_callback_table[#{rettype}][#{fnum}] = &rb_dl_callback_func_#{rettype.to_s}_#{fnum};"
|
||||
return code
|
||||
end
|
||||
|
||||
DLTYPE.keys.sort.each{|t|
|
||||
if( DLTYPE[t][:cb] )
|
||||
rec_output([t])
|
||||
for n in 0..(MAX_CALLBACK - 1)
|
||||
print(mktable(t, n, 15), "\n")
|
||||
end
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ module LIBC
|
|||
end
|
||||
|
||||
|
||||
$cb1 = DL.set_callback('IPP', 0){|ptr1, ptr2|
|
||||
$cb1 = DL.callback('IPP'){|ptr1, ptr2|
|
||||
str1 = ptr1.ptr.to_s
|
||||
str2 = ptr2.ptr.to_s
|
||||
str1 <=> str2
|
||||
|
|
|
@ -38,8 +38,6 @@ print("MINOR_VERSION = #{DL::MINOR_VERSION}\n")
|
|||
print("\n")
|
||||
print("DLSTACK = #{DL::DLSTACK}\n")
|
||||
print("MAX_ARG = #{DL::MAX_ARG}\n")
|
||||
print("MAX_CBARG = #{DL::MAX_CBARG}\n")
|
||||
print("MAX_CBENT = #{DL::MAX_CBENT}\n")
|
||||
print("\n")
|
||||
print("DL::FREE = #{DL::FREE.inspect}\n")
|
||||
print("\n")
|
||||
|
@ -205,8 +203,7 @@ debug r,rs
|
|||
assert("callback1", :must, r == 1)
|
||||
|
||||
|
||||
callback2 = DL.set_callback("LLP", 0){|arg1,arg2|
|
||||
ptr = arg2 # DL::PtrData.new(arg2)
|
||||
callback2 = DL.callback("LLP"){|num,ptr|
|
||||
msg = ptr.to_s
|
||||
if( msg == "callback message" )
|
||||
2
|
||||
|
@ -218,7 +215,7 @@ debug callback2
|
|||
r,rs = h["test_call_func1", "IP"][callback2]
|
||||
debug r,rs
|
||||
assert("callback2", :must, r == 2)
|
||||
|
||||
DL.remove_callback(callback2)
|
||||
|
||||
ptr = DL.malloc(DL.sizeof('CL'))
|
||||
ptr.struct!("CL", :c, :l)
|
||||
|
|
Loading…
Add table
Reference in a new issue