From 87ff4b24ae4911bda46a5426024959c278da69b2 Mon Sep 17 00:00:00 2001 From: drbrain Date: Mon, 15 Aug 2011 23:48:59 +0000 Subject: * 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 --- ChangeLog | 6 ++++ ext/.document | 1 - ext/fiddle/closure.c | 44 +++++++++++++++++++++++++++ ext/fiddle/fiddle.c | 56 ++++++++++++++++++++++++++++++++++ ext/fiddle/function.c | 63 +++++++++++++++++++++++++++++++++++++++ ext/fiddle/lib/fiddle.rb | 7 +++++ ext/fiddle/lib/fiddle/closure.rb | 31 +++++++++++++++++++ ext/fiddle/lib/fiddle/function.rb | 1 + 8 files changed, 208 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e82e4fd118..23f83e4402 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Tue Aug 16 08:48:26 2011 Eric Hodel + + * 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 * ext/socket: Make Socket documentation appear. Add documentation for diff --git a/ext/.document b/ext/.document index f93dfd29b1..c51b8a7b63 100644 --- a/ext/.document +++ b/ext/.document @@ -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 diff --git a/ext/fiddle/closure.c b/ext/fiddle/closure.c index 48520997bc..542d978395 100644 --- a/ext/fiddle/closure.c +++ b/ext/fiddle/closure.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, []) + * => #<#:0x0000000150d240> + * func = Fiddle::Function.new(closure, [], Fiddle::TYPE_INT) + * => # + * 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 */ diff --git a/ext/fiddle/fiddle.c b/ext/fiddle/fiddle.c index 2580ac0e53..08fdb4484d 100644 --- a/ext/fiddle/fiddle.c +++ b/ext/fiddle/fiddle.c @@ -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 diff --git a/ext/fiddle/function.c b/ext/fiddle/function.c index 911c9b80fc..6e8909991a 100644 --- a/ext/fiddle/function.c +++ b/ext/fiddle/function.c @@ -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" + * => # + * f = Fiddle::Function.new(@libc['strcpy'], [TYPE_VOIDP, TYPE_VOIDP], TYPE_VOIDP) + * => # + * buff = "000" + * => "000" + * str = f.call(buff, "123") + * => # + * str.to_s + * => "123" + * + * === ABI check + * + * @libc = DL.dlopen "/lib/libc.so.6" + * => # + * f = Fiddle::Function.new(@libc['strcpy'], [TYPE_VOIDP, TYPE_VOIDP], TYPE_VOIDP) + * => # + * 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: */ diff --git a/ext/fiddle/lib/fiddle.rb b/ext/fiddle/lib/fiddle.rb index 8b8c069b03..7d55a1f7ad 100644 --- a/ext/fiddle/lib/fiddle.rb +++ b/ext/fiddle/lib/fiddle.rb @@ -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 diff --git a/ext/fiddle/lib/fiddle/closure.rb b/ext/fiddle/lib/fiddle/closure.rb index dc2b7a65be..beb90ecbe5 100644 --- a/ext/fiddle/lib/fiddle/closure.rb +++ b/ext/fiddle/lib/fiddle/closure.rb @@ -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 diff --git a/ext/fiddle/lib/fiddle/function.rb b/ext/fiddle/lib/fiddle/function.rb index 7b9e735874..1657682498 100644 --- a/ext/fiddle/lib/fiddle/function.rb +++ b/ext/fiddle/lib/fiddle/function.rb @@ -1,5 +1,6 @@ module Fiddle class Function + # The ABI of the Function. attr_reader :abi end end -- cgit v1.2.3