static VALUE
rb_dl_callback(int argc, VALUE argv[], VALUE self)
{
VALUE type, proc;
int rettype, entry, i;
char fname[127];
rb_secure(4);
proc = Qnil;
switch (rb_scan_args(argc, argv, "11", &type, &proc)) {
case 1:
if (rb_block_given_p()) {
proc = rb_block_proc();
}
else{
proc = Qnil;
}
default:
break;
}
StringValue(type);
switch (RSTRING(type)->ptr[0]) {
case '0':
rettype = 0x00;
break;
case 'C':
rettype = 0x01;
break;
case 'H':
rettype = 0x02;
break;
case 'I':
rettype = 0x03;
break;
case 'L':
rettype = 0x04;
break;
case 'F':
rettype = 0x05;
break;
case 'D':
rettype = 0x06;
break;
case 'P':
rettype = 0x07;
break;
default:
rb_raise(rb_eDLTypeError, "unsupported type `%c'", RSTRING(type)->ptr[0]);
}
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((void (*)())rb_dl_callback_table[rettype][entry],
fname, RSTRING(type)->ptr);
}
static VALUE
rb_dl_callback(int argc, VALUE argv[], VALUE self)
{
VALUE type, proc;
int rettype, entry, i;
char fname[127];
rb_secure(4);
proc = Qnil;
switch (rb_scan_args(argc, argv, "11", &type, &proc)) {
case 1:
if (rb_block_given_p()) {
proc = rb_block_proc();
}
else{
proc = Qnil;
}
default:
break;
}
StringValue(type);
switch (RSTRING(type)->ptr[0]) {
case '0':
rettype = 0x00;
break;
case 'C':
rettype = 0x01;
break;
case 'H':
rettype = 0x02;
break;
case 'I':
rettype = 0x03;
break;
case 'L':
rettype = 0x04;
break;
case 'F':
rettype = 0x05;
break;
case 'D':
rettype = 0x06;
break;
case 'P':
rettype = 0x07;
break;
default:
rb_raise(rb_eDLTypeError, "unsupported type `%c'", RSTRING(type)->ptr[0]);
}
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((void (*)())rb_dl_callback_table[rettype][entry],
fname, RSTRING(type)->ptr);
}
VALUE
rb_dl_dlopen(int argc, VALUE argv[], VALUE self)
{
rb_secure(2);
return rb_class_new_instance(argc, argv, rb_cDLHandle);
}
VALUE
rb_dl_malloc(VALUE self, VALUE size)
{
rb_secure(4);
return rb_dlptr_malloc(DLNUM2LONG(size), dlfree);
}
static VALUE
rb_dl_remove_callback(VALUE mod, VALUE sym)
{
freefunc_t f;
int i, j;
rb_secure(4);
f = rb_dlsym2csym(sym);
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;
}