Module: DL::Importer
Overview
DL::Importer includes the means to dynamically load libraries and build modules around them including calling extern functions within the C library that has been loaded.
Example
require 'dl'
require 'dl/import'
module LibSum
extend DL::Importer
dlload './libsum.so'
extern 'double sum(double*, int)'
extern 'double split(double)'
end
Constant Summary
Constants included
from DL
ALIGN_CHAR, ALIGN_DOUBLE, ALIGN_FLOAT, ALIGN_INT, ALIGN_LONG, ALIGN_LONG_LONG, ALIGN_SHORT, ALIGN_VOIDP, BUILD_RUBY_PLATFORM, BUILD_RUBY_VERSION, CdeclCallbackAddrs, CdeclCallbackProcs, DLSTACK_SIZE, MAX_CALLBACK, NULL, RTLD_GLOBAL, RTLD_LAZY, RTLD_NOW, RUBY_FREE, SEM, SIZEOF_CHAR, SIZEOF_DOUBLE, SIZEOF_FLOAT, SIZEOF_INT, SIZEOF_LONG, SIZEOF_LONG_LONG, SIZEOF_SHORT, SIZEOF_VOIDP, StdcallCallbackAddrs, StdcallCallbackProcs, TYPE_CHAR, TYPE_DOUBLE, TYPE_FLOAT, TYPE_INT, TYPE_LONG, TYPE_LONG_LONG, TYPE_SHORT, TYPE_VOID, TYPE_VOIDP
Instance Method Summary
collapse
-
#[](name) ⇒ Object
-
#bind(signature, *opts, &blk) ⇒ Object
-
#bind_function(name, ctype, argtype, call_type = nil, &block) ⇒ Object
-
#create_carried_function(name, ctype, argtype, call_type = nil, n = 0) ⇒ Object
-
#create_temp_function(name, ctype, argtype, call_type = nil) ⇒ Object
-
#create_value(ty, val = nil) ⇒ Object
(also: #value)
-
#dlload(*libs) ⇒ Object
-
#extern(signature, *opts) ⇒ Object
-
#handler ⇒ Object
-
#import_function(name, ctype, argtype, call_type = nil) ⇒ Object
-
#import_symbol(name) ⇒ Object
-
#import_value(ty, addr) ⇒ Object
-
#sizeof(ty) ⇒ Object
-
#struct(signature) ⇒ Object
-
#typealias(alias_type, orig_type) ⇒ Object
-
#union(signature) ⇒ Object
Methods included from CParser
#parse_ctype, #parse_signature, #parse_struct_signature
Methods included from DL
dlopen, dlunwrap, dlwrap, fiddle?, free, malloc, realloc, #remove_callback_internal, #remove_cdecl_callback, #remove_stdcall_callback, #set_callback_internal, #set_cdecl_callback, #set_stdcall_callback
Instance Method Details
#[](name) ⇒ Object
192
193
194
|
# File 'lib/dl/import.rb', line 192
def [](name)
@func_map[name]
end
|
#bind(signature, *opts, &blk) ⇒ Object
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
|
# File 'lib/dl/import.rb', line 152
def bind(signature, *opts, &blk)
name, ctype, argtype = parse_signature(signature, @type_alias)
h = parse_bind_options(opts)
case h[:callback_type]
when :bind, nil
f = bind_function(name, ctype, argtype, h[:call_type], &blk)
when :temp, :temporal
f = create_temp_function(name, ctype, argtype, h[:call_type])
when :carried
f = create_carried_function(name, ctype, argtype, h[:call_type], h[:carrier])
else
raise(RuntimeError, "unknown callback type: #{h[:callback_type]}")
end
@func_map[name] = f
begin
/^(.+?):(\d+)/ =~ caller.first
file, line = $1, $2.to_i
rescue
file, line = __FILE__, __LINE__+3
end
module_eval(<<-EOS, file, line)
def #{name}(*args,&block)
@func_map['#{name}'].call(*args,&block)
end
EOS
module_function(name)
f
end
|
#bind_function(name, ctype, argtype, call_type = nil, &block) ⇒ Object
232
233
234
235
236
237
238
239
240
241
242
243
244
|
# File 'lib/dl/import.rb', line 232
def bind_function(name, ctype, argtype, call_type = nil, &block)
if DL.fiddle?
closure = Class.new(Fiddle::Closure) {
define_method(:call, block)
}.new(ctype, argtype)
Function.new(closure, argtype)
else
f = Function.new(CFunc.new(0, ctype, name, call_type || :cdecl), argtype)
f.bind(&block)
f
end
end
|
#create_carried_function(name, ctype, argtype, call_type = nil, n = 0) ⇒ Object
250
251
252
|
# File 'lib/dl/import.rb', line 250
def create_carried_function(name, ctype, argtype, call_type = nil, n = 0)
CarriedFunction.new(CFunc.new(0, ctype, name, call_type || :cdecl), argtype, n)
end
|
#create_temp_function(name, ctype, argtype, call_type = nil) ⇒ Object
246
247
248
|
# File 'lib/dl/import.rb', line 246
def create_temp_function(name, ctype, argtype, call_type = nil)
TempFunction.new(CFunc.new(0, ctype, name, call_type || :cdecl), argtype)
end
|
#create_value(ty, val = nil) ⇒ Object
Also known as:
value
196
197
198
199
200
201
202
203
|
# File 'lib/dl/import.rb', line 196
def create_value(ty, val=nil)
s = struct([ty + " value"])
ptr = s.malloc()
if( val )
ptr.value = val
end
return ptr
end
|
#dlload(*libs) ⇒ Object
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
# File 'lib/dl/import.rb', line 55
def dlload(*libs)
handles = libs.collect{|lib|
case lib
when nil
nil
when Handle
lib
when Importer
lib.handlers
else
begin
DL.dlopen(lib)
rescue DLError
raise(DLError, "can't load #{lib}")
end
end
}.flatten()
@handler = CompositeHandler.new(handles)
@func_map = {}
@type_alias = {}
end
|
#extern(signature, *opts) ⇒ Object
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
# File 'lib/dl/import.rb', line 130
def extern(signature, *opts)
symname, ctype, argtype = parse_signature(signature, @type_alias)
opt = parse_bind_options(opts)
f = import_function(symname, ctype, argtype, opt[:call_type])
name = symname.gsub(/@.+/,'')
@func_map[name] = f
begin
/^(.+?):(\d+)/ =~ caller.first
file, line = $1, $2.to_i
rescue
file, line = __FILE__, __LINE__+3
end
module_eval(<<-EOS, file, line)
def #{name}(*args, &block)
@func_map['#{name}'].call(*args,&block)
end
EOS
module_function(name)
f
end
|
#handler ⇒ Object
212
213
214
|
# File 'lib/dl/import.rb', line 212
def handler
@handler or raise "call dlload before importing symbols and functions"
end
|
#import_function(name, ctype, argtype, call_type = nil) ⇒ Object
224
225
226
227
228
229
230
|
# File 'lib/dl/import.rb', line 224
def import_function(name, ctype, argtype, call_type = nil)
addr = handler.sym(name)
if( !addr )
raise(DLError, "cannot find the function: #{name}()")
end
Function.new(CFunc.new(addr, ctype, name, call_type || :cdecl), argtype)
end
|
#import_symbol(name) ⇒ Object
216
217
218
219
220
221
222
|
# File 'lib/dl/import.rb', line 216
def import_symbol(name)
addr = handler.sym(name)
if( !addr )
raise(DLError, "cannot find the symbol: #{name}")
end
CPtr.new(addr)
end
|
#import_value(ty, addr) ⇒ Object
206
207
208
209
210
|
# File 'lib/dl/import.rb', line 206
def import_value(ty, addr)
s = struct([ty + " value"])
ptr = s.new(addr)
return ptr
end
|
#struct(signature) ⇒ Object
182
183
184
185
|
# File 'lib/dl/import.rb', line 182
def struct(signature)
tys, mems = parse_struct_signature(signature, @type_alias)
DL::CStructBuilder.create(CStruct, tys, mems)
end
|
#typealias(alias_type, orig_type) ⇒ Object
77
78
79
|
# File 'lib/dl/import.rb', line 77
def typealias(alias_type, orig_type)
@type_alias[alias_type] = orig_type
end
|
#union(signature) ⇒ Object
187
188
189
190
|
# File 'lib/dl/import.rb', line 187
def union(signature)
tys, mems = parse_struct_signature(signature, @type_alias)
DL::CStructBuilder.create(CUnion, tys, mems)
end
|