In Files

  • dl/lib/dl/func.rb

DL::Function

Public Class Methods

new(cfunc, argtypes, &proc) click to toggle source
 
               # File dl/lib/dl/func.rb, line 12
def initialize(cfunc, argtypes, &proc)
  @cfunc = cfunc
  @stack = Stack.new(argtypes.collect{|ty| ty.abs})
  if( @cfunc.ctype < 0 )
    @cfunc.ctype = @cfunc.ctype.abs
    @unsigned = true
  end
  if( proc )
    bind(&proc)
  end
end
            

Public Instance Methods

bind(&block) click to toggle source
 
               # File dl/lib/dl/func.rb, line 56
def bind(&block)
  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
            
bind_at_call(&block) click to toggle source
 
               # File dl/lib/dl/func.rb, line 104
def bind_at_call(&block)
  bind(&block)
end
            
bound?() click to toggle source
 
               # File dl/lib/dl/func.rb, line 100
def bound?()
  @cfunc.ptr != 0
end
            
call(*args, &block) click to toggle source
 
               # File dl/lib/dl/func.rb, line 34
def call(*args, &block)
  funcs = []
  args.each{|e| check_safe_obj(e) }
  check_safe_obj(block)
  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
            
check_safe_obj(val) click to toggle source
 
               # File dl/lib/dl/func.rb, line 28
def check_safe_obj(val)
  if $SAFE > 0 and val.tainted?
    raise SecurityError, 'Insecure operation'
  end
end
            
to_i() click to toggle source
 
               # File dl/lib/dl/func.rb, line 24
def to_i()
  @cfunc.to_i
end
            
unbind() click to toggle source
 
               # File dl/lib/dl/func.rb, line 86
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() click to toggle source
 
               # File dl/lib/dl/func.rb, line 108
def unbind_at_call()
end
            
wrap_result(r) click to toggle source
 
               # File dl/lib/dl/func.rb, line 44
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