From 5c1bdda10cc0febcac126532cf6f3aac51c08271 Mon Sep 17 00:00:00 2001 From: ttate Date: Mon, 10 Jun 2002 17:47:48 +0000 Subject: Add DL::Importable::Internal::callback(). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2541 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/dl/lib/dl/import.rb | 56 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 9 deletions(-) (limited to 'ext/dl/lib/dl') diff --git a/ext/dl/lib/dl/import.rb b/ext/dl/lib/dl/import.rb index 42e89515c8..5d221f2816 100644 --- a/ext/dl/lib/dl/import.rb +++ b/ext/dl/lib/dl/import.rb @@ -37,10 +37,7 @@ module DL end alias dllink :dlload - # example: - # extern "int strlen(char*)" - # - def extern(proto) + def parse_cproto(proto) proto = proto.gsub(/\s+/, " ").strip case proto when /^([\d\w\*_\s]+)\(([\d\w\*_\s\,\[\]]*)\)$/ @@ -54,12 +51,52 @@ module DL ret.push("*") end ret = ret.join(" ") - return import(func, ret, args) + return [func, ret, args] else raise(RuntimeError,"can't parse the function prototype: #{proto}") end end + # example: + # extern "int strlen(char*)" + # + def extern(proto) + func,ret,args = parse_cproto(proto) + return import(func, ret, args) + end + + # example: + # callback "int method_name(int, char*)" + # + def callback(proto) + func,ret,args = parse_cproto(proto) + + init_types() + init_sym() + + rty,_,rdec = @types.encode_type(ret) + ty,enc,dec = encode_types(args) + symty = rty + ty + + module_eval("module_function :#{func}") + sym = module_eval [ + "DL::callback(\"#{symty}\"){|*args|", + " sym,rdec,enc,dec = @SYM['#{func}']", + " args = enc.call(args) if enc", + " r,rs = #{func}(*args)", + " r = rdec.call(r) if rdec", + " rs = dec.call(rs) if dec", + " @retval = r", + " @args = rs", + " @retval", + "}", + ].join("\n") + + @SYM[func] = [sym,rdec,enc,dec] + + return sym + end + # example: # typealias("uint", "unsigned int") # @@ -74,11 +111,12 @@ module DL def import(name, rettype, argtypes = nil) init_types() init_sym() - @LIBS.each{|lib| - rty,_,rdec = @types.encode_type(rettype) - ty,enc,dec = encode_types(argtypes) - symty = rty + ty + rty,_,rdec = @types.encode_type(rettype) + ty,enc,dec = encode_types(argtypes) + symty = rty + ty + + @LIBS.each{|lib| begin sym = lib[name, symty] rescue -- cgit v1.2.3