parent
# File dl/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
# File dl/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
# File dl/lib/dl/func.rb, line 138
def bind_at_call(&block)
bind(&block)
end
# File dl/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
# File dl/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