| Module | DL::Importable::Internal |
| In: |
dl/struct.rb
dl/import.rb |
Classes and Modules
Class DL::Importable::Internal::MemoryClass DL::Importable::Internal::Struct
Class DL::Importable::Internal::Union
Public Instance methods
example:
callback "int method_name(int, char*)"
# File dl/import.rb, line 67
67: def callback(proto)
68: func,ret,args = parse_cproto(proto)
69:
70: init_types()
71: init_sym()
72:
73: rty,renc,rdec = @types.encode_return_type(ret)
74: if( !rty )
75: raise(TypeError, "unsupported type: #{ret}")
76: end
77: ty,enc,dec = encode_argument_types(args)
78: symty = rty + ty
79:
80: module_eval("module_function :#{func}")
81: sym = module_eval([
82: "DL::callback(\"#{symty}\"){|*args|",
83: " sym,rdec,enc,dec = @SYM['#{func}']",
84: " args = enc.call(args) if enc",
85: " r,rs = #{func}(*args)",
86: " r = renc.call(r) if rdec",
87: " rs = dec.call(rs) if (dec && rs)",
88: " @retval = r",
89: " @args = rs",
90: " @retval",
91: "}",
92: ].join("\n"))
93:
94: @SYM[func] = [sym,rdec,enc,dec]
95:
96: return sym
97: end
# File dl/struct.rb, line 9
9: def define_struct(contents)
10: init_types()
11: Struct.new(@types, contents)
12: end
# File dl/struct.rb, line 15
15: def define_union(contents)
16: init_types()
17: Union.new(@types, contents)
18: end
# File dl/import.rb, line 23
23: def dlload(*libnames)
24: if( !defined?(@LIBS) )
25: @LIBS = []
26: end
27: libnames.each{|libname|
28: if( !LIB_MAP[libname] )
29: LIB_MAP[libname] = DL.dlopen(libname)
30: end
31: @LIBS.push(LIB_MAP[libname])
32: }
33: end
# File dl/import.rb, line 188
188: def encode_argument_types(tys)
189: init_types()
190: encty = []
191: enc = nil
192: dec = nil
193: tys.each_with_index{|ty,idx|
194: ty,c1,c2 = @types.encode_argument_type(ty)
195: if( !ty )
196: raise(TypeError, "unsupported type: #{ty}")
197: end
198: encty.push(ty)
199: if( enc )
200: if( c1 )
201: conv1 = enc
202: enc = proc{|v| v = conv1.call(v); v[idx] = c1.call(v[idx]); v}
203: end
204: else
205: if( c1 )
206: enc = proc{|v| v[idx] = c1.call(v[idx]); v}
207: end
208: end
209: if( dec )
210: if( c2 )
211: conv2 = dec
212: dec = proc{|v| v = conv2.call(v); v[idx] = c2.call(v[idx]); v}
213: end
214: else
215: if( c2 )
216: dec = proc{|v| v[idx] = c2.call(v[idx]); v}
217: end
218: end
219: }
220: return [encty.join, enc, dec]
221: end
example:
extern "int strlen(char*)"
# File dl/import.rb, line 59
59: def extern(proto)
60: func,ret,args = parse_cproto(proto)
61: return import(func, ret, args)
62: end
example:
import("get_length", "int", ["void*", "int"])
# File dl/import.rb, line 134
134: def import(name, rettype, argtypes = nil)
135: init_types()
136: init_sym()
137:
138: rty,_,rdec = @types.encode_return_type(rettype)
139: if( !rty )
140: raise(TypeError, "unsupported type: #{rettype}")
141: end
142: ty,enc,dec = encode_argument_types(argtypes)
143: symty = rty + ty
144:
145: sym = symbol(name, symty)
146:
147: mname = name.dup
148: if( ?A <= mname[0] && mname[0] <= ?Z )
149: mname[0,1] = mname[0,1].downcase
150: end
151: @SYM[mname] = [sym,rdec,enc,dec]
152:
153: module_eval [
154: "def #{mname}(*args)",
155: " sym,rdec,enc,dec = @SYM['#{mname}']",
156: " args = enc.call(args) if enc",
157: if( $DEBUG )
158: " p \"[DL] call #{mname} with \#{args.inspect}\""
159: else
160: ""
161: end,
162: " r,rs = sym.call(*args)",
163: if( $DEBUG )
164: " p \"[DL] retval=\#{r.inspect} args=\#{rs.inspect}\""
165: else
166: ""
167: end,
168: " r = rdec.call(r) if rdec",
169: " rs = dec.call(rs) if dec",
170: " @retval = r",
171: " @args = rs",
172: " return @retval",
173: "end",
174: "module_function :#{mname}",
175: ].join("\n")
176:
177: return sym
178: end
# File dl/import.rb, line 36
36: def parse_cproto(proto)
37: proto = proto.gsub(/\s+/, " ").strip
38: case proto
39: when /^([\d\w\*_\s]+)\(([\d\w\*_\s\,\[\]]*)\)$/
40: ret = $1
41: args = $2.strip()
42: ret = ret.split(/\s+/)
43: args = args.split(/\s*,\s*/)
44: func = ret.pop()
45: if( func =~ /^\*/ )
46: func.gsub!(/^\*+/,"")
47: ret.push("*")
48: end
49: ret = ret.join(" ")
50: return [func, ret, args]
51: else
52: raise(RuntimeError,"can't parse the function prototype: #{proto}")
53: end
54: end
example:
symbol "foo_value" symbol "foo_func", "IIP"
# File dl/import.rb, line 112
112: def symbol(name, ty = nil)
113: sym = nil
114: @LIBS.each{|lib|
115: begin
116: if( ty )
117: sym = lib[name, ty]
118: else
119: sym = lib[name]
120: end
121: rescue
122: next
123: end
124: }
125: if( !sym )
126: raise(RuntimeError, "can't find the symbol `#{name}'")
127: end
128: return sym
129: end