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:
parent
48a86f5ffa
commit
7bcc135504
147
ext/dl/handle.c
147
ext/dl/handle.c
@ -125,64 +125,109 @@ rb_dlhandle_to_i(VALUE self)
|
|||||||
VALUE
|
VALUE
|
||||||
rb_dlhandle_sym(VALUE self, VALUE sym)
|
rb_dlhandle_sym(VALUE self, VALUE sym)
|
||||||
{
|
{
|
||||||
void (*func)();
|
void (*func)();
|
||||||
struct sym_data *data;
|
struct sym_data *data;
|
||||||
struct dl_handle *dlhandle;
|
struct dl_handle *dlhandle;
|
||||||
void *handle;
|
void *handle;
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *err;
|
const char *err;
|
||||||
|
|
||||||
rb_secure(2);
|
rb_secure(2);
|
||||||
|
|
||||||
if( sym == Qnil ){
|
if( sym == Qnil ){
|
||||||
#if defined(RTLD_NEXT)
|
#if defined(RTLD_NEXT)
|
||||||
name = RTLD_NEXT;
|
name = RTLD_NEXT;
|
||||||
#else
|
#else
|
||||||
name = NULL;
|
name = NULL;
|
||||||
#endif
|
#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
|
else{
|
||||||
rb_raise(rb_eDLError, "Unknown symbol \"%s\".", name);
|
name = StringValuePtr(sym);
|
||||||
#endif
|
}
|
||||||
}
|
|
||||||
|
|
||||||
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
|
void
|
||||||
|
@ -39,7 +39,7 @@ module DL
|
|||||||
tymap ||= {}
|
tymap ||= {}
|
||||||
signature = signature.gsub(/\s+/, " ").strip
|
signature = signature.gsub(/\s+/, " ").strip
|
||||||
case signature
|
case signature
|
||||||
when /^([\d\w\*_\s]+)\(([\d\w\*_\s\,\[\]]*)\)$/
|
when /^([\d\w@\*_\s]+)\(([\d\w\*_\s\,\[\]]*)\)$/
|
||||||
ret = $1
|
ret = $1
|
||||||
args = $2
|
args = $2
|
||||||
ret = ret.split(/\s+/)
|
ret = ret.split(/\s+/)
|
||||||
|
@ -27,7 +27,7 @@ module DL
|
|||||||
|
|
||||||
def call(*args, &block)
|
def call(*args, &block)
|
||||||
funcs = []
|
funcs = []
|
||||||
args = wrap_args(args, nil, funcs, &block)
|
args = wrap_args(args, @stack.types, funcs, &block)
|
||||||
r = @cfunc.call(@stack.pack(args))
|
r = @cfunc.call(@stack.pack(args))
|
||||||
funcs.each{|f| f.unbind_at_call()}
|
funcs.each{|f| f.unbind_at_call()}
|
||||||
return wrap_result(r)
|
return wrap_result(r)
|
||||||
@ -59,7 +59,7 @@ module DL
|
|||||||
end
|
end
|
||||||
}
|
}
|
||||||
r = block.call(*ary)
|
r = block.call(*ary)
|
||||||
wrap_arg(r, nil, [])
|
wrap_arg(r, @cfunc.ctype, [])
|
||||||
}
|
}
|
||||||
case @cfunc.calltype
|
case @cfunc.calltype
|
||||||
when :cdecl
|
when :cdecl
|
||||||
|
@ -113,9 +113,10 @@ module DL
|
|||||||
private :parse_bind_options
|
private :parse_bind_options
|
||||||
|
|
||||||
def extern(signature, *opts)
|
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)
|
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
|
@func_map[name] = f
|
||||||
#define_method(name){|*args,&block| f.call(*args,&block)}
|
#define_method(name){|*args,&block| f.call(*args,&block)}
|
||||||
module_eval(<<-EOS)
|
module_eval(<<-EOS)
|
||||||
|
@ -50,6 +50,13 @@ module DL
|
|||||||
case arg
|
case arg
|
||||||
when CPtr
|
when CPtr
|
||||||
return arg.to_i
|
return arg.to_i
|
||||||
|
when IO
|
||||||
|
case ty
|
||||||
|
when TYPE_VOIDP
|
||||||
|
return CPtr[arg].to_i
|
||||||
|
else
|
||||||
|
return arg.to_i
|
||||||
|
end
|
||||||
when Function
|
when Function
|
||||||
if( block )
|
if( block )
|
||||||
arg.bind_at_call(&block)
|
arg.bind_at_call(&block)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user