зеркало из https://github.com/github/ruby.git
* 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:
Родитель
8977d3e30c
Коммит
87ff4b24ae
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче