1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Improved DL::Handle#sym.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@7911 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ttate 2005-02-07 09:45:02 +00:00
parent 48a86f5ffa
commit 7bcc135504
5 changed files with 109 additions and 56 deletions

View file

@ -125,64 +125,109 @@ rb_dlhandle_to_i(VALUE self)
VALUE
rb_dlhandle_sym(VALUE self, VALUE sym)
{
void (*func)();
struct sym_data *data;
struct dl_handle *dlhandle;
void *handle;
const char *name;
const char *err;
void (*func)();
struct sym_data *data;
struct dl_handle *dlhandle;
void *handle;
const char *name;
const char *err;
rb_secure(2);
rb_secure(2);
if( sym == Qnil ){
if( sym == Qnil ){
#if defined(RTLD_NEXT)
name = RTLD_NEXT;
name = RTLD_NEXT;
#else
name = NULL;
name = NULL;
#endif
}
else{
name = StringValuePtr(sym);
}
Data_Get_Struct(self, struct dl_handle, dlhandle);
if( ! dlhandle->open ){
rb_raise(rb_eDLError, "Closed handle.");
}
handle = dlhandle->ptr;
func = dlsym(handle, name);
#if defined(HAVE_DLERROR)
if( !func && (err = dlerror()) )
#else
if( !func )
#endif
{
#if defined(__CYGWIN__) || defined(WIN32) || defined(__MINGW32__)
{
int len = strlen(name);
char *name_a = (char*)xmalloc(len+2);
strcpy(name_a, name);
name_a[len] = 'A';
name_a[len+1] = '\0';
func = dlsym(handle, name_a);
xfree(name_a);
#if defined(HAVE_DLERROR)
if( !func && (err = dlerror()) )
#else
if( !func )
#endif
{
rb_raise(rb_eDLError, "Unknown symbol \"%sA\".", name);
}
}
#else
rb_raise(rb_eDLError, "Unknown symbol \"%s\".", name);
#endif
}
else{
name = StringValuePtr(sym);
}
return PTR2NUM(func);
Data_Get_Struct(self, struct dl_handle, dlhandle);
if( ! dlhandle->open ){
rb_raise(rb_eDLError, "Closed handle.");
}
handle = dlhandle->ptr;
func = dlsym(handle, name);
#if defined(HAVE_DLERROR)
if( !func && (err = dlerror()) )
#else
if( !func )
#endif
{
#if defined(__CYGWIN__) || defined(WIN32) || defined(__MINGW32__)
{
int len = strlen(name);
int i;
char *name_a = (char*)xmalloc(len+2);
strcpy(name_a, name);
name_a[len] = 'A';
name_a[len+1] = '\0';
func = dlsym(handle, name_a);
xfree(name_a);
#if defined(HAVE_DLERROR)
if( !func && (err = dlerror()) )
#else
if( !func )
#endif
{
for( i = 0; i < 256; i += 4 ){
int len = strlen(name);
char *name_n = (char*)xmalloc(len+5);
sprintf(name_n, "%s@%d%c", name, i, 0);
func = dlsym(handle, name_n);
xfree(name_n);
#if defined(HAVE_DLERROR)
if( func || !(err = dlerror()) )
#else
if( func )
#endif
{
break;
}
}
#if defined(HAVE_DLERROR)
if( !func && (err = dlerror()) )
#else
if( !func )
#endif
{
rb_raise(rb_eDLError, "Unknown symbol \"%s\".", name);
}
}
}
#else
for( i = 0; i < 256; i += 4 ){
int len = strlen(name);
char *name_n = (char*)xmalloc(len+4);
sprintf(name_n, "%s@%d", name, i);
func = dlsym(handle, name_n);
xfree(name_n);
#if defined(HAVE_DLERROR)
if( func || !(err = dlerror()) )
#else
if( func )
#endif
{
break;
}
}
#if defined(HAVE_DLERROR)
if( !func && (err = dlerror()) )
#else
if( !func )
#endif
{
rb_raise(rb_eDLError, "Unknown symbol \"%s\".", name);
}
#endif
}
return PTR2NUM(func);
}
void

View file

@ -39,7 +39,7 @@ module DL
tymap ||= {}
signature = signature.gsub(/\s+/, " ").strip
case signature
when /^([\d\w\*_\s]+)\(([\d\w\*_\s\,\[\]]*)\)$/
when /^([\d\w@\*_\s]+)\(([\d\w\*_\s\,\[\]]*)\)$/
ret = $1
args = $2
ret = ret.split(/\s+/)

View file

@ -27,7 +27,7 @@ module DL
def call(*args, &block)
funcs = []
args = wrap_args(args, nil, funcs, &block)
args = wrap_args(args, @stack.types, funcs, &block)
r = @cfunc.call(@stack.pack(args))
funcs.each{|f| f.unbind_at_call()}
return wrap_result(r)
@ -59,7 +59,7 @@ module DL
end
}
r = block.call(*ary)
wrap_arg(r, nil, [])
wrap_arg(r, @cfunc.ctype, [])
}
case @cfunc.calltype
when :cdecl

View file

@ -113,9 +113,10 @@ module DL
private :parse_bind_options
def extern(signature, *opts)
name, ctype, argtype = parse_signature(signature, @type_alias)
symname, ctype, argtype = parse_signature(signature, @type_alias)
opt = parse_bind_options(opts)
f = import_function(name, ctype, argtype, opt[:call_type])
f = import_function(symname, ctype, argtype, opt[:call_type])
name = symname.gsub(/@.+/,'')
@func_map[name] = f
#define_method(name){|*args,&block| f.call(*args,&block)}
module_eval(<<-EOS)

View file

@ -50,6 +50,13 @@ module DL
case arg
when CPtr
return arg.to_i
when IO
case ty
when TYPE_VOIDP
return CPtr[arg].to_i
else
return arg.to_i
end
when Function
if( block )
arg.bind_at_call(&block)