Class: DL::Function
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
Methods included from ValueUtil
#signed_value, #unsigned_value, #wrap_arg, #wrap_args
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
Constructor Details
#initialize(cfunc, argtypes, abi = nil, &block) ⇒ Function
Returns a new instance of Function.
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
# File 'lib/dl/func.rb', line 14
def initialize cfunc, argtypes, abi = nil, &block
if DL.fiddle?
abi ||= Fiddle::Function::DEFAULT
if block_given?
@cfunc = Class.new(Fiddle::Closure) {
define_method(:call, block)
}.new(cfunc.ctype, argtypes)
else
@cfunc = cfunc
end
@args = argtypes
super(@cfunc, @args.reject { |x| x == TYPE_VOID }, cfunc.ctype, abi)
else
@cfunc = cfunc
@stack = Stack.new(argtypes.collect{|ty| ty.abs})
if( @cfunc.ctype < 0 )
@cfunc.ctype = @cfunc.ctype.abs
@unsigned = true
else
@unsigned = false
end
if block_given?
bind(&block)
end
end
end
|
Instance Method Details
#bind(&block) ⇒ Object
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
# File 'lib/dl/func.rb', line 77
def bind(&block)
if DL.fiddle?
@cfunc = Class.new(Fiddle::Closure) {
def initialize ctype, args, block
super(ctype, args)
@block = block
end
def call *args
@block.call(*args)
end
}.new(@cfunc.ctype, @args, block)
else
if( !block )
raise(RuntimeError, "block must be given.")
end
if( @cfunc.ptr == 0 )
cb = Proc.new{|*args|
ary = @stack.unpack(args)
@stack.types.each_with_index{|ty, idx|
case ty
when TYPE_VOIDP
ary[idx] = CPtr.new(ary[idx])
end
}
r = block.call(*ary)
wrap_arg(r, @cfunc.ctype, [])
}
case @cfunc.calltype
when :cdecl
@cfunc.ptr = set_cdecl_callback(@cfunc.ctype, @stack.size, &cb)
when :stdcall
@cfunc.ptr = set_stdcall_callback(@cfunc.ctype, @stack.size, &cb)
else
raise(RuntimeError, "unsupported calltype: #{@cfunc.calltype}")
end
if( @cfunc.ptr == 0 )
raise(RuntimeException, "can't bind C function.")
end
end
end
end
|
#bind_at_call(&block) ⇒ Object
138
139
140
|
# File 'lib/dl/func.rb', line 138
def bind_at_call(&block)
bind(&block)
end
|
#bound? ⇒ Boolean
134
135
136
|
# File 'lib/dl/func.rb', line 134
def bound?()
@cfunc.ptr != 0
end
|
#call(*args, &block) ⇒ Object
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
# File 'lib/dl/func.rb', line 50
def call(*args, &block)
if DL.fiddle?
if block_given?
args.find { |a| DL::Function === a }.bind_at_call(&block)
end
super
else
funcs = []
_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)
end
end
|
#name ⇒ Object
46
47
48
|
# File 'lib/dl/func.rb', line 46
def name
@cfunc.name
end
|
#to_i ⇒ Object
42
43
44
|
# File 'lib/dl/func.rb', line 42
def to_i()
@cfunc.to_i
end
|
#unbind ⇒ Object
120
121
122
123
124
125
126
127
128
129
130
131
132
|
# File 'lib/dl/func.rb', line 120
def unbind()
if( @cfunc.ptr != 0 )
case @cfunc.calltype
when :cdecl
remove_cdecl_callback(@cfunc.ptr, @cfunc.ctype)
when :stdcall
remove_stdcall_callback(@cfunc.ptr, @cfunc.ctype)
else
raise(RuntimeError, "unsupported calltype: #{@cfunc.calltype}")
end
@cfunc.ptr = 0
end
end
|
#unbind_at_call ⇒ Object
142
143
|
# File 'lib/dl/func.rb', line 142
def unbind_at_call()
end
|
#wrap_result(r) ⇒ Object
65
66
67
68
69
70
71
72
73
74
75
|
# File 'lib/dl/func.rb', line 65
def wrap_result(r)
case @cfunc.ctype
when TYPE_VOIDP
r = CPtr.new(r)
else
if( @unsigned )
r = unsigned_value(r, @cfunc.ctype)
end
end
r
end
|