summaryrefslogtreecommitdiffstats
path: root/ext/dl
diff options
context:
space:
mode:
authorttate <ttate@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2005-02-07 09:45:02 +0000
committerttate <ttate@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2005-02-07 09:45:02 +0000
commitd888290695c898d7f175f7ff65f966d464c59b95 (patch)
treecf1236e58aba577543c8788adbca32293d2d4ad4 /ext/dl
parent92abb38f46d5121c052d7f9865607c031e535ebd (diff)
downloadruby-d888290695c898d7f175f7ff65f966d464c59b95.tar.gz
ruby-d888290695c898d7f175f7ff65f966d464c59b95.tar.xz
ruby-d888290695c898d7f175f7ff65f966d464c59b95.zip
Improved DL::Handle#sym.
git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@7911 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/dl')
-rw-r--r--ext/dl/handle.c125
-rw-r--r--ext/dl/lib/dl/cparser.rb2
-rw-r--r--ext/dl/lib/dl/func.rb4
-rw-r--r--ext/dl/lib/dl/import.rb5
-rw-r--r--ext/dl/lib/dl/value.rb7
5 files changed, 98 insertions, 45 deletions
diff --git a/ext/dl/handle.c b/ext/dl/handle.c
index 7f5ce1216..d30105169 100644
--- a/ext/dl/handle.c
+++ b/ext/dl/handle.c
@@ -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);
- }
+ }
+ else{
+ name = StringValuePtr(sym);
+ }
- Data_Get_Struct(self, struct dl_handle, dlhandle);
- if( ! dlhandle->open ){
- rb_raise(rb_eDLError, "Closed handle.");
- }
- handle = dlhandle->ptr;
+ Data_Get_Struct(self, struct dl_handle, dlhandle);
+ if( ! dlhandle->open ){
+ rb_raise(rb_eDLError, "Closed handle.");
+ }
+ handle = dlhandle->ptr;
- func = dlsym(handle, name);
+ func = dlsym(handle, name);
#if defined(HAVE_DLERROR)
- if( !func && (err = dlerror()) )
+ if( !func && (err = dlerror()) )
#else
- if( !func )
+ 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(__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()) )
+ if( !func && (err = dlerror()) )
#else
- if( !func )
+ if( !func )
#endif
- {
- rb_raise(rb_eDLError, "Unknown symbol \"%sA\".", name);
- }
- }
+ {
+ 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
- rb_raise(rb_eDLError, "Unknown symbol \"%s\".", name);
+ 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);
+ return PTR2NUM(func);
}
void
diff --git a/ext/dl/lib/dl/cparser.rb b/ext/dl/lib/dl/cparser.rb
index 5b5dd5f47..c897d1b69 100644
--- a/ext/dl/lib/dl/cparser.rb
+++ b/ext/dl/lib/dl/cparser.rb
@@ -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+/)
diff --git a/ext/dl/lib/dl/func.rb b/ext/dl/lib/dl/func.rb
index 121f2efcc..b29aebcc8 100644
--- a/ext/dl/lib/dl/func.rb
+++ b/ext/dl/lib/dl/func.rb
@@ -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
diff --git a/ext/dl/lib/dl/import.rb b/ext/dl/lib/dl/import.rb
index 2ad805598..ebd84eb47 100644
--- a/ext/dl/lib/dl/import.rb
+++ b/ext/dl/lib/dl/import.rb
@@ -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)
diff --git a/ext/dl/lib/dl/value.rb b/ext/dl/lib/dl/value.rb
index 1357106a4..aa7e0dd32 100644
--- a/ext/dl/lib/dl/value.rb
+++ b/ext/dl/lib/dl/value.rb
@@ -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)