Extended maintenance of Ruby versions 1.8.7 and 1.9.2 ended on July 31, 2014. Read more

In Files

  • dl/lib/dl/func.rb

DL::Function

Public Class Methods

new(cfunc, argtypes, abi = nil, &block) click to toggle source
 
               # 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
            

Public Instance Methods

bind(&block) click to toggle source
 
               # 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
            
bind_at_call(&block) click to toggle source
 
               # File dl/lib/dl/func.rb, line 138
def bind_at_call(&block)
  bind(&block)
end
            
bound?() click to toggle source
 
               # File dl/lib/dl/func.rb, line 134
def bound?()
  @cfunc.ptr != 0
end
            
call(*args, &block) click to toggle source
 
               # 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
            
name() click to toggle source
 
               # File dl/lib/dl/func.rb, line 46
def name
  @cfunc.name
end
            
to_i() click to toggle source
 
               # File dl/lib/dl/func.rb, line 42
def to_i()
  @cfunc.to_i
end
            
unbind() click to toggle source
 
               # 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
            
unbind_at_call() click to toggle source
 
               # File dl/lib/dl/func.rb, line 142
def unbind_at_call()
end
            
wrap_result(r) click to toggle source
 
               # File dl/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
            

Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.

If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.

If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.

If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.

blog comments powered by Disqus