mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	* ext/.document (fiddle): Remove duplicate entry
* ext/fiddle: Complete documentation of Fiddle. Patch by Vincent Batts. [#5192] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32981 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									8977d3e30c
								
							
						
					
					
						commit
						87ff4b24ae
					
				
					 8 changed files with 208 additions and 1 deletions
				
			
		| 
						 | 
				
			
			@ -1,3 +1,9 @@
 | 
			
		|||
Tue Aug 16 08:48:26 2011  Eric Hodel  <drbrain@segment7.net>
 | 
			
		||||
 | 
			
		||||
	* ext/.document (fiddle):  Remove duplicate entry
 | 
			
		||||
	* ext/fiddle:  Complete documentation of Fiddle.  Patch by Vincent
 | 
			
		||||
	  Batts.  [#5192]
 | 
			
		||||
 | 
			
		||||
Tue Aug 16 08:00:15 2011  Eric Hodel  <drbrain@segment7.net>
 | 
			
		||||
 | 
			
		||||
	* ext/socket:  Make Socket documentation appear.  Add documentation for
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,7 +24,6 @@ fcntl/fcntl.c
 | 
			
		|||
fiddle/closure.c
 | 
			
		||||
fiddle/conversions.c
 | 
			
		||||
fiddle/fiddle.c
 | 
			
		||||
fiddle/fiddle.c
 | 
			
		||||
fiddle/function.c
 | 
			
		||||
fiddle/lib
 | 
			
		||||
gdbm/gdbm.c
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -224,11 +224,55 @@ to_i(VALUE self)
 | 
			
		|||
void
 | 
			
		||||
Init_fiddle_closure()
 | 
			
		||||
{
 | 
			
		||||
#if 0
 | 
			
		||||
    mFiddle = rb_define_module("Fiddle"); /* let rdoc know about mFiddle */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Document-class: Fiddle::Closure
 | 
			
		||||
     *
 | 
			
		||||
     * == Description
 | 
			
		||||
     *
 | 
			
		||||
     * An FFI closure wrapper, for handling callbacks.
 | 
			
		||||
     *
 | 
			
		||||
     * == Example
 | 
			
		||||
     *
 | 
			
		||||
     *   closure = Class.new(Fiddle::Closure) {
 | 
			
		||||
     *     def call
 | 
			
		||||
     *       10
 | 
			
		||||
     *     end
 | 
			
		||||
     *   }.new(Fiddle::TYPE_INT, [])
 | 
			
		||||
     *   => #<#<Class:0x0000000150d308>:0x0000000150d240>
 | 
			
		||||
     *   func = Fiddle::Function.new(closure, [], Fiddle::TYPE_INT)
 | 
			
		||||
     *   => #<Fiddle::Function:0x00000001516e58>
 | 
			
		||||
     *   func.call
 | 
			
		||||
     *   => 10
 | 
			
		||||
     */
 | 
			
		||||
    cFiddleClosure = rb_define_class_under(mFiddle, "Closure", rb_cObject);
 | 
			
		||||
 | 
			
		||||
    rb_define_alloc_func(cFiddleClosure, allocate);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Document-method: new
 | 
			
		||||
     *
 | 
			
		||||
     * call-seq: new(ret, *args, abi = Fiddle::DEFAULT)
 | 
			
		||||
     *
 | 
			
		||||
     * Construct a new Closure object.
 | 
			
		||||
     *
 | 
			
		||||
     * * +ret+ is the C type to be returned
 | 
			
		||||
     * * +args+ are passed the callback
 | 
			
		||||
     * * +abi+ is the abi of the closure
 | 
			
		||||
     *
 | 
			
		||||
     * If there is an error in preparing the ffi_cif or ffi_prep_closure,
 | 
			
		||||
     * then a RuntimeError will be raised.
 | 
			
		||||
     */
 | 
			
		||||
    rb_define_method(cFiddleClosure, "initialize", initialize, -1);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Document-method: to_i
 | 
			
		||||
     *
 | 
			
		||||
     * Returns the memory address for this closure
 | 
			
		||||
     */
 | 
			
		||||
    rb_define_method(cFiddleClosure, "to_i", to_i, 0);
 | 
			
		||||
}
 | 
			
		||||
/* vim: set noet sw=4 sts=4 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,20 +4,76 @@ VALUE mFiddle;
 | 
			
		|||
 | 
			
		||||
void Init_fiddle()
 | 
			
		||||
{
 | 
			
		||||
    /*
 | 
			
		||||
     * Document-module: Fiddle
 | 
			
		||||
     *
 | 
			
		||||
     * == Description
 | 
			
		||||
     *
 | 
			
		||||
     * A libffi wrapper.
 | 
			
		||||
     *
 | 
			
		||||
     */
 | 
			
		||||
    mFiddle = rb_define_module("Fiddle");
 | 
			
		||||
 | 
			
		||||
    /* Document-const: TYPE_VOID
 | 
			
		||||
     *
 | 
			
		||||
     * C type - void
 | 
			
		||||
     */
 | 
			
		||||
    rb_define_const(mFiddle, "TYPE_VOID",      INT2NUM(TYPE_VOID));
 | 
			
		||||
 | 
			
		||||
    /* Document-const: TYPE_VOIDP
 | 
			
		||||
     *
 | 
			
		||||
     * C type - void*
 | 
			
		||||
     */
 | 
			
		||||
    rb_define_const(mFiddle, "TYPE_VOIDP",     INT2NUM(TYPE_VOIDP));
 | 
			
		||||
 | 
			
		||||
    /* Document-const: TYPE_CHAR
 | 
			
		||||
     *
 | 
			
		||||
     * C type - char
 | 
			
		||||
     */
 | 
			
		||||
    rb_define_const(mFiddle, "TYPE_CHAR",      INT2NUM(TYPE_CHAR));
 | 
			
		||||
 | 
			
		||||
    /* Document-const: TYPE_SHORT
 | 
			
		||||
     *
 | 
			
		||||
     * C type - short
 | 
			
		||||
     */
 | 
			
		||||
    rb_define_const(mFiddle, "TYPE_SHORT",     INT2NUM(TYPE_SHORT));
 | 
			
		||||
 | 
			
		||||
    /* Document-const: TYPE_INT
 | 
			
		||||
     *
 | 
			
		||||
     * C type - int
 | 
			
		||||
     */
 | 
			
		||||
    rb_define_const(mFiddle, "TYPE_INT",       INT2NUM(TYPE_INT));
 | 
			
		||||
 | 
			
		||||
    /* Document-const: TYPE_LONG
 | 
			
		||||
     *
 | 
			
		||||
     * C type - long
 | 
			
		||||
     */
 | 
			
		||||
    rb_define_const(mFiddle, "TYPE_LONG",      INT2NUM(TYPE_LONG));
 | 
			
		||||
 | 
			
		||||
#if HAVE_LONG_LONG
 | 
			
		||||
    /* Document-const: TYPE_LONG_LONG
 | 
			
		||||
     *
 | 
			
		||||
     * C type - long long
 | 
			
		||||
     */
 | 
			
		||||
    rb_define_const(mFiddle, "TYPE_LONG_LONG", INT2NUM(TYPE_LONG_LONG));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    /* Document-const: TYPE_FLOAT
 | 
			
		||||
     *
 | 
			
		||||
     * C type - float
 | 
			
		||||
     */
 | 
			
		||||
    rb_define_const(mFiddle, "TYPE_FLOAT",     INT2NUM(TYPE_FLOAT));
 | 
			
		||||
 | 
			
		||||
    /* Document-const: TYPE_DOUBLE
 | 
			
		||||
     *
 | 
			
		||||
     * C type - double
 | 
			
		||||
     */
 | 
			
		||||
    rb_define_const(mFiddle, "TYPE_DOUBLE",    INT2NUM(TYPE_DOUBLE));
 | 
			
		||||
 | 
			
		||||
    /* Document-const: WINDOWS
 | 
			
		||||
     *
 | 
			
		||||
     * Returns a boolean regarding whether the host is WIN32
 | 
			
		||||
     */
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
    rb_define_const(mFiddle, "WINDOWS", Qtrue);
 | 
			
		||||
#else
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -138,17 +138,80 @@ function_call(int argc, VALUE argv[], VALUE self)
 | 
			
		|||
void
 | 
			
		||||
Init_fiddle_function(void)
 | 
			
		||||
{
 | 
			
		||||
    /*
 | 
			
		||||
     * Document-class: Fiddle::Function
 | 
			
		||||
     *
 | 
			
		||||
     * == Description
 | 
			
		||||
     *
 | 
			
		||||
     * A representation of a C function
 | 
			
		||||
     *
 | 
			
		||||
     * == Examples
 | 
			
		||||
     *
 | 
			
		||||
     * === 'strcpy'
 | 
			
		||||
     *
 | 
			
		||||
     *   @libc = DL.dlopen "/lib/libc.so.6"
 | 
			
		||||
     *   => #<DL::Handle:0x00000001d7a8d8>
 | 
			
		||||
     *   f = Fiddle::Function.new(@libc['strcpy'], [TYPE_VOIDP, TYPE_VOIDP], TYPE_VOIDP)
 | 
			
		||||
     *   => #<Fiddle::Function:0x00000001d8ee00>
 | 
			
		||||
     *   buff = "000"
 | 
			
		||||
     *   => "000"
 | 
			
		||||
     *   str = f.call(buff, "123")
 | 
			
		||||
     *   => #<DL::CPtr:0x00000001d0c380 ptr=0x000000018a21b8 size=0 free=0x00000000000000>
 | 
			
		||||
     *   str.to_s
 | 
			
		||||
     *   => "123"
 | 
			
		||||
     *
 | 
			
		||||
     * === ABI check
 | 
			
		||||
     *
 | 
			
		||||
     *   @libc = DL.dlopen "/lib/libc.so.6"
 | 
			
		||||
     *   => #<DL::Handle:0x00000001d7a8d8>
 | 
			
		||||
     *   f = Fiddle::Function.new(@libc['strcpy'], [TYPE_VOIDP, TYPE_VOIDP], TYPE_VOIDP)
 | 
			
		||||
     *   => #<Fiddle::Function:0x00000001d8ee00>
 | 
			
		||||
     *   f.abi == Fiddle::Function::DEFAULT
 | 
			
		||||
     *   => true
 | 
			
		||||
     */
 | 
			
		||||
    cFiddleFunction = rb_define_class_under(mFiddle, "Function", rb_cObject);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Document-const: DEFAULT
 | 
			
		||||
     *
 | 
			
		||||
     * Default ABI
 | 
			
		||||
     *
 | 
			
		||||
     */
 | 
			
		||||
    rb_define_const(cFiddleFunction, "DEFAULT", INT2NUM(FFI_DEFAULT_ABI));
 | 
			
		||||
 | 
			
		||||
#ifdef FFI_STDCALL
 | 
			
		||||
    /*
 | 
			
		||||
     * Document-const: STDCALL
 | 
			
		||||
     *
 | 
			
		||||
     * FFI implementation of WIN32 stdcall convention
 | 
			
		||||
     *
 | 
			
		||||
     */
 | 
			
		||||
    rb_define_const(cFiddleFunction, "STDCALL", INT2NUM(FFI_STDCALL));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    rb_define_alloc_func(cFiddleFunction, allocate);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Document-method: call
 | 
			
		||||
     *
 | 
			
		||||
     * Calls the constructed Function, with +args+
 | 
			
		||||
     *
 | 
			
		||||
     * For an example see Fiddle::Function
 | 
			
		||||
     *
 | 
			
		||||
     */
 | 
			
		||||
    rb_define_method(cFiddleFunction, "call", function_call, -1);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Document-method: new
 | 
			
		||||
     * call-seq: new(ptr, *args, ret_type, abi = DEFAULT)
 | 
			
		||||
     *
 | 
			
		||||
     * Constructs a Function object.
 | 
			
		||||
     * * +ptr+ is a referenced function, of a DL::Handle
 | 
			
		||||
     * * +args+ is an Array of arguments, passed to the +ptr+ function
 | 
			
		||||
     * * +ret_type+ is the return type of the function
 | 
			
		||||
     * * +abi+ is the ABI of the function
 | 
			
		||||
     *
 | 
			
		||||
     */
 | 
			
		||||
    rb_define_method(cFiddleFunction, "initialize", initialize, -1);
 | 
			
		||||
}
 | 
			
		||||
/* vim: set noet sws=4 sw=4: */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,22 +4,29 @@ require 'fiddle/closure'
 | 
			
		|||
require 'dl' unless Object.const_defined?(:DL)
 | 
			
		||||
 | 
			
		||||
module Fiddle
 | 
			
		||||
 | 
			
		||||
  # A reference to DL::CPtr
 | 
			
		||||
  Pointer = DL::CPtr
 | 
			
		||||
 | 
			
		||||
  if WINDOWS
 | 
			
		||||
    # Returns the last win32 +Error+ of the current executing +Thread+ or nil
 | 
			
		||||
    # if none
 | 
			
		||||
    def self.win32_last_error
 | 
			
		||||
      Thread.current[:__FIDDLE_WIN32_LAST_ERROR__]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Sets the last win32 +Error+ of the current executing +Thread+ to +error+
 | 
			
		||||
    def self.win32_last_error= error
 | 
			
		||||
      Thread.current[:__FIDDLE_WIN32_LAST_ERROR__] = error
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Returns the last +Error+ of the current executing +Thread+ or nil if none
 | 
			
		||||
  def self.last_error
 | 
			
		||||
    Thread.current[:__FIDDLE_LAST_ERROR__]
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Sets the last +Error+ of the current executing +Thread+ to +error+
 | 
			
		||||
  def self.last_error= error
 | 
			
		||||
    Thread.current[:__DL2_LAST_ERROR__] = error
 | 
			
		||||
    Thread.current[:__FIDDLE_LAST_ERROR__] = error
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,14 +1,45 @@
 | 
			
		|||
module Fiddle
 | 
			
		||||
  class Closure
 | 
			
		||||
 | 
			
		||||
    # the C type of the return of the FFI closure
 | 
			
		||||
    attr_reader :ctype
 | 
			
		||||
 | 
			
		||||
    # arguments of the FFI closure
 | 
			
		||||
    attr_reader :args
 | 
			
		||||
 | 
			
		||||
    # Extends Fiddle::Closure to allow for building the closure in a block
 | 
			
		||||
    class BlockCaller < Fiddle::Closure
 | 
			
		||||
 | 
			
		||||
      # == Description
 | 
			
		||||
      #
 | 
			
		||||
      # Construct a new BlockCaller object.
 | 
			
		||||
      #
 | 
			
		||||
      # * +ctype+ is the C type to be returned
 | 
			
		||||
      # * +args+ are passed the callback
 | 
			
		||||
      # * +abi+ is the abi of the closure
 | 
			
		||||
      #
 | 
			
		||||
      # If there is an error in preparing the +ffi_cif+ or +ffi_prep_closure+,
 | 
			
		||||
      # then a RuntimeError will be raised.
 | 
			
		||||
      #
 | 
			
		||||
      # == Example
 | 
			
		||||
      #
 | 
			
		||||
      #   include Fiddle
 | 
			
		||||
      #
 | 
			
		||||
      #   cb = Closure::BlockCaller.new(TYPE_INT, [TYPE_INT]) do |one|
 | 
			
		||||
      #     one
 | 
			
		||||
      #   end
 | 
			
		||||
      #
 | 
			
		||||
      #   func = Function.new(cb, [TYPE_INT], TYPE_INT)
 | 
			
		||||
      #
 | 
			
		||||
      def initialize ctype, args, abi = Fiddle::Function::DEFAULT, &block
 | 
			
		||||
        super(ctype, args, abi)
 | 
			
		||||
        @block = block
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Calls the constructed BlockCaller, with +args+
 | 
			
		||||
      #
 | 
			
		||||
      # For an example see Fiddle::Closure::BlockCaller.new
 | 
			
		||||
      #
 | 
			
		||||
      def call *args
 | 
			
		||||
        @block.call(*args)
 | 
			
		||||
      end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
module Fiddle
 | 
			
		||||
  class Function
 | 
			
		||||
    # The ABI of the Function.
 | 
			
		||||
    attr_reader :abi
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue