1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* ext/fiddle/closure.c: Documentation for Fiddle

* ext/fiddle/pointer.c: ditto
* ext/fiddle/function.c: ditto
* ext/fiddle/lib/fiddle.rb: ditto
* ext/fiddle/fiddle.c: ditto
* ext/fiddle/handle.c: ditto



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37909 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
zzak 2012-11-27 23:26:07 +00:00
parent 7e4b6fa7d6
commit 9c831edbf4
7 changed files with 127 additions and 55 deletions

View file

@ -1,3 +1,12 @@
Wed Nov 28 08:25:00 2012 Zachary Scott <zachary@zacharyscott.net>
* ext/fiddle/closure.c: Documentation for Fiddle
* ext/fiddle/pointer.c: ditto
* ext/fiddle/function.c: ditto
* ext/fiddle/lib/fiddle.rb: ditto
* ext/fiddle/fiddle.c: ditto
* ext/fiddle/handle.c: ditto
Wed Nov 28 04:53:40 2012 Aaron Patterson <aaron@tenderlovemaking.com> Wed Nov 28 04:53:40 2012 Aaron Patterson <aaron@tenderlovemaking.com>
* ext/fiddle/handle.c: Make Fiddle independent of DL, copy DL::Handle * ext/fiddle/handle.c: Make Fiddle independent of DL, copy DL::Handle

View file

@ -271,11 +271,11 @@ Init_fiddle_closure()
* 10 * 10
* end * end
* }.new(Fiddle::TYPE_INT, []) * }.new(Fiddle::TYPE_INT, [])
* => #<#<Class:0x0000000150d308>:0x0000000150d240> * #=> #<#<Class:0x0000000150d308>:0x0000000150d240>
* func = Fiddle::Function.new(closure, [], Fiddle::TYPE_INT) * func = Fiddle::Function.new(closure, [], Fiddle::TYPE_INT)
* => #<Fiddle::Function:0x00000001516e58> * #=> #<Fiddle::Function:0x00000001516e58>
* func.call * func.call
* => 10 * #=> 10
*/ */
cFiddleClosure = rb_define_class_under(mFiddle, "Closure", rb_cObject); cFiddleClosure = rb_define_class_under(mFiddle, "Closure", rb_cObject);

View file

@ -135,9 +135,34 @@ Init_fiddle(void)
/* /*
* Document-module: Fiddle * Document-module: Fiddle
* *
* A libffi wrapper for Ruby.
*
* == Description * == Description
* *
* A libffi wrapper. * Fiddle is an extension to translate a foreign function interface (FFI)
* with ruby.
*
* It wraps {libffi}[http://sourceware.org/libffi/], a popular C library
* which provides a portable interface that allows code written in one
* language to clal code written in another language.
*
* == Example
*
* Here we will use Fiddle::Function to wrap {floor(3) from
* libm}[http://linux.die.net/man/3/floor]
*
* require 'fiddle'
*
* libm = Fiddle.dlopen('/lib/libm.so.6')
*
* floor = Fiddle::Function.new(
* libm['floor'],
* [Fiddle::TYPE_DOUBLE],
* Fiddle::TYPE_DOUBLE
* )
*
* puts floor.call(3.14159) #=> 3.0
*
* *
*/ */
mFiddle = rb_define_module("Fiddle"); mFiddle = rb_define_module("Fiddle");

View file

@ -161,25 +161,28 @@ Init_fiddle_function(void)
* *
* === 'strcpy' * === 'strcpy'
* *
* @libc = DL.dlopen "/lib/libc.so.6" * @libc = Fiddle.dlopen "/lib/libc.so.6"
* => #<DL::Handle:0x00000001d7a8d8> * #=> #<Fiddle::Handle:0x00000001d7a8d8>
* f = Fiddle::Function.new(@libc['strcpy'], [TYPE_VOIDP, TYPE_VOIDP], TYPE_VOIDP) * f = Fiddle::Function.new(
* => #<Fiddle::Function:0x00000001d8ee00> * @libc['strcpy'],
* [Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP],
* Fiddle::TYPE_VOIDP)
* #=> #<Fiddle::Function:0x00000001d8ee00>
* buff = "000" * buff = "000"
* => "000" * #=> "000"
* str = f.call(buff, "123") * str = f.call(buff, "123")
* => #<DL::CPtr:0x00000001d0c380 ptr=0x000000018a21b8 size=0 free=0x00000000000000> * #=> #<Fiddle::Pointer:0x00000001d0c380 ptr=0x000000018a21b8 size=0 free=0x00000000000000>
* str.to_s * str.to_s
* => "123" * => "123"
* *
* === ABI check * === ABI check
* *
* @libc = DL.dlopen "/lib/libc.so.6" * @libc = DL.dlopen "/lib/libc.so.6"
* => #<DL::Handle:0x00000001d7a8d8> * #=> #<Fiddle::Handle:0x00000001d7a8d8>
* f = Fiddle::Function.new(@libc['strcpy'], [TYPE_VOIDP, TYPE_VOIDP], TYPE_VOIDP) * f = Fiddle::Function.new(@libc['strcpy'], [TYPE_VOIDP, TYPE_VOIDP], TYPE_VOIDP)
* => #<Fiddle::Function:0x00000001d8ee00> * #=> #<Fiddle::Function:0x00000001d8ee00>
* f.abi == Fiddle::Function::DEFAULT * f.abi == Fiddle::Function::DEFAULT
* => true * #=> true
*/ */
cFiddleFunction = rb_define_class_under(mFiddle, "Function", rb_cObject); cFiddleFunction = rb_define_class_under(mFiddle, "Function", rb_cObject);
@ -218,7 +221,7 @@ Init_fiddle_function(void)
* call-seq: new(ptr, *args, ret_type, abi = DEFAULT) * call-seq: new(ptr, *args, ret_type, abi = DEFAULT)
* *
* Constructs a Function object. * Constructs a Function object.
* * +ptr+ is a referenced function, of a DL::Handle * * +ptr+ is a referenced function, of a Fiddle::Handle
* * +args+ is an Array of arguments, passed to the +ptr+ function * * +args+ is an Array of arguments, passed to the +ptr+ function
* * +ret_type+ is the return type of the function * * +ret_type+ is the return type of the function
* * +abi+ is the ABI of the function * * +abi+ is the ABI of the function

View file

@ -56,8 +56,9 @@ static const rb_data_type_t fiddle_handle_data_type = {
/* /*
* call-seq: close * call-seq: close
* *
* Close this Fiddle::Handle. Calling close more than once will raise a * Close this handle.
* Fiddle::DLError exception. *
* Calling close more than once will raise a Fiddle::DLError exception.
*/ */
static VALUE static VALUE
rb_fiddle_handle_close(VALUE self) rb_fiddle_handle_close(VALUE self)
@ -112,7 +113,7 @@ predefined_fiddle_handle(void *handle)
/* /*
* call-seq: * call-seq:
* initialize(lib = nil, flags = Fiddle::RTLD_LAZY | Fiddle::RTLD_GLOBAL) * new(lib = nil, flags = Fiddle::RTLD_LAZY | Fiddle::RTLD_GLOBAL)
* *
* Create a new handler that opens library named +lib+ with +flags+. If no * Create a new handler that opens library named +lib+ with +flags+. If no
* library is specified, RTLD_DEFAULT is used. * library is specified, RTLD_DEFAULT is used.
@ -194,7 +195,7 @@ rb_fiddle_handle_initialize(int argc, VALUE argv[], VALUE self)
/* /*
* call-seq: enable_close * call-seq: enable_close
* *
* Enable a call to dlclose() when this Fiddle::Handle is garbage collected. * Enable a call to dlclose() when this handle is garbage collected.
*/ */
static VALUE static VALUE
rb_fiddle_handle_enable_close(VALUE self) rb_fiddle_handle_enable_close(VALUE self)
@ -209,7 +210,7 @@ rb_fiddle_handle_enable_close(VALUE self)
/* /*
* call-seq: disable_close * call-seq: disable_close
* *
* Disable a call to dlclose() when this Fiddle::Handle is garbage collected. * Disable a call to dlclose() when this handle is garbage collected.
*/ */
static VALUE static VALUE
rb_fiddle_handle_disable_close(VALUE self) rb_fiddle_handle_disable_close(VALUE self)
@ -224,8 +225,9 @@ rb_fiddle_handle_disable_close(VALUE self)
/* /*
* call-seq: close_enabled? * call-seq: close_enabled?
* *
* Returns +true+ if dlclose() will be called when this Fiddle::Handle is * Returns +true+ if dlclose() will be called when this handle is garbage collected.
* garbage collected. *
* See man(3) dlclose() for more info.
*/ */
static VALUE static VALUE
rb_fiddle_handle_close_enabled_p(VALUE self) rb_fiddle_handle_close_enabled_p(VALUE self)
@ -256,7 +258,6 @@ static VALUE fiddle_handle_sym(void *handle, const char *symbol);
/* /*
* Document-method: sym * Document-method: sym
* Document-method: []
* *
* call-seq: sym(name) * call-seq: sym(name)
* *
@ -284,12 +285,13 @@ rb_fiddle_handle_sym(VALUE self, VALUE sym)
/* /*
* Document-method: sym * Document-method: sym
* Document-method: []
* *
* call-seq: sym(name) * call-seq: sym(name)
* *
* Get the address as an Integer for the function named +name+. The function * Get the address as an Integer for the function named +name+. The function
* is searched via dlsym on RTLD_NEXT. See man(3) dlsym() for more info. * is searched via dlsym on RTLD_NEXT.
*
* See man(3) dlsym() for more info.
*/ */
static VALUE static VALUE
rb_fiddle_handle_s_sym(VALUE self, VALUE sym) rb_fiddle_handle_s_sym(VALUE self, VALUE sym)
@ -386,6 +388,8 @@ Init_fiddle_handle(void)
* @handle = Fiddle::Handle.new(libc_so, Fiddle::RTLD_LAZY | Fiddle::RTLD_GLOBAL) * @handle = Fiddle::Handle.new(libc_so, Fiddle::RTLD_LAZY | Fiddle::RTLD_GLOBAL)
* => #<Fiddle::Handle:0x00000000d69ef8> * => #<Fiddle::Handle:0x00000000d69ef8>
* *
* See RTLD_LAZY and RTLD_GLOBAL
*
* === Addresses to symbols * === Addresses to symbols
* *
* strcpy_addr = @handle['strcpy'] * strcpy_addr = @handle['strcpy']
@ -447,8 +451,8 @@ Init_fiddle_handle(void)
* *
* If this value is specified or the environment variable LD_BIND_NOW is * If this value is specified or the environment variable LD_BIND_NOW is
* set to a nonempty string, all undefined symbols in the library are * set to a nonempty string, all undefined symbols in the library are
* resolved before dlopen() returns. If this cannot be done an error is * resolved before Fiddle.dlopen returns. If this cannot be done an error
* returned. * is returned.
*/ */
rb_define_const(rb_cHandle, "RTLD_NOW", INT2NUM(RTLD_NOW)); rb_define_const(rb_cHandle, "RTLD_NOW", INT2NUM(RTLD_NOW));

View file

@ -27,6 +27,12 @@ module Fiddle
Thread.current[:__FIDDLE_LAST_ERROR__] = error Thread.current[:__FIDDLE_LAST_ERROR__] = error
end end
# call-seq: dlopen(library) => Fiddle::Handle
#
# Creates a new handler that opens +library+, and returns an instance of
# Fiddle::Handle.
#
# See Fiddle::Handle.new for more.
def dlopen library def dlopen library
Fiddle::Handle.new library Fiddle::Handle.new library
end end

View file

@ -140,11 +140,12 @@ rb_fiddle_ptr_s_allocate(VALUE klass)
/* /*
* call-seq: * call-seq:
* Fiddle::Pointer.new(address) => fiddle_cptr * Fiddle::Pointer.new(address) => fiddle_cptr
* Fiddle::Pointer.new(address, size) => fiddle_cptr * new(address, size) => fiddle_cptr
* Fiddle::Pointer.new(address, size, freefunc) => fiddle_cptr * new(address, size, freefunc) => fiddle_cptr
* *
* Create a new pointer to +address+ with an optional +size+ and +freefunc+. * Create a new pointer to +address+ with an optional +size+ and +freefunc+.
*
* +freefunc+ will be called when the instance is garbage collected. * +freefunc+ will be called when the instance is garbage collected.
*/ */
static VALUE static VALUE
@ -191,6 +192,7 @@ rb_fiddle_ptr_initialize(int argc, VALUE argv[], VALUE self)
* *
* Allocate +size+ bytes of memory and associate it with an optional * Allocate +size+ bytes of memory and associate it with an optional
* +freefunc+ that will be called when the pointer is garbage collected. * +freefunc+ that will be called when the pointer is garbage collected.
*
* +freefunc+ must be an address pointing to a function or an instance of * +freefunc+ must be an address pointing to a function or an instance of
* Fiddle::Function * Fiddle::Function
*/ */
@ -223,7 +225,7 @@ rb_fiddle_ptr_s_malloc(int argc, VALUE argv[], VALUE klass)
/* /*
* call-seq: to_i * call-seq: to_i
* *
* Returns the integer memory location of this DL::CPtr. * Returns the integer memory location of this pointer.
*/ */
static VALUE static VALUE
rb_fiddle_ptr_to_i(VALUE self) rb_fiddle_ptr_to_i(VALUE self)
@ -237,7 +239,7 @@ rb_fiddle_ptr_to_i(VALUE self)
/* /*
* call-seq: to_value * call-seq: to_value
* *
* Cast this CPtr to a ruby object. * Cast this pointer to a ruby object.
*/ */
static VALUE static VALUE
rb_fiddle_ptr_to_value(VALUE self) rb_fiddle_ptr_to_value(VALUE self)
@ -250,7 +252,9 @@ rb_fiddle_ptr_to_value(VALUE self)
/* /*
* call-seq: ptr * call-seq: ptr
* *
* Returns a DL::CPtr that is a dereferenced pointer for this DL::CPtr. * Returns a new Fiddle::Pointer instance that is a dereferenced pointer for
* this pointer.
*
* Analogous to the star operator in C. * Analogous to the star operator in C.
*/ */
static VALUE static VALUE
@ -265,7 +269,9 @@ rb_fiddle_ptr_ptr(VALUE self)
/* /*
* call-seq: ref * call-seq: ref
* *
* Returns a DL::CPtr that is a reference pointer for this DL::CPtr. * Returns a new Fiddle::Pointer instance that is a reference pointer for this
* pointer.
*
* Analogous to the ampersand operator in C. * Analogous to the ampersand operator in C.
*/ */
static VALUE static VALUE
@ -280,7 +286,7 @@ rb_fiddle_ptr_ref(VALUE self)
/* /*
* call-seq: null? * call-seq: null?
* *
* Returns true if this is a null pointer. * Returns +true+ if this is a null pointer.
*/ */
static VALUE static VALUE
rb_fiddle_ptr_null_p(VALUE self) rb_fiddle_ptr_null_p(VALUE self)
@ -294,7 +300,8 @@ rb_fiddle_ptr_null_p(VALUE self)
/* /*
* call-seq: free=(function) * call-seq: free=(function)
* *
* Set the free function for this pointer to the DL::CFunc in +function+. * Set the free function for this pointer to +function+ in the given
* Fiddle::Function.
*/ */
static VALUE static VALUE
rb_fiddle_ptr_free_set(VALUE self, VALUE val) rb_fiddle_ptr_free_set(VALUE self, VALUE val)
@ -308,9 +315,13 @@ rb_fiddle_ptr_free_set(VALUE self, VALUE val)
} }
/* /*
* call-seq: free * call-seq: free => Fiddle::Function
* *
* Get the free function for this pointer. Returns Fiddle::Function. * Get the free function for this pointer.
*
* Returns a new instance of Fiddle::Function.
*
* See Fiddle::Function.new
*/ */
static VALUE static VALUE
rb_fiddle_ptr_free_get(VALUE self) rb_fiddle_ptr_free_get(VALUE self)
@ -339,9 +350,14 @@ rb_fiddle_ptr_free_get(VALUE self)
* ptr.to_s => string * ptr.to_s => string
* ptr.to_s(len) => string * ptr.to_s(len) => string
* *
* Returns the pointer contents as a string. When called with no arguments, * Returns the pointer contents as a string.
* this method will return the contents until the first NULL byte. When *
* called with +len+, a string of +len+ bytes will be returned. * When called with no arguments, this method will return the contents until
* the first NULL byte.
*
* When called with +len+, a string of +len+ bytes will be returned.
*
* See to_str
*/ */
static VALUE static VALUE
rb_fiddle_ptr_to_s(int argc, VALUE argv[], VALUE self) rb_fiddle_ptr_to_s(int argc, VALUE argv[], VALUE self)
@ -372,9 +388,14 @@ rb_fiddle_ptr_to_s(int argc, VALUE argv[], VALUE self)
* ptr.to_str => string * ptr.to_str => string
* ptr.to_str(len) => string * ptr.to_str(len) => string
* *
* Returns the pointer contents as a string. When called with no arguments, * Returns the pointer contents as a string.
* this method will return the contents with the length of this pointer's *
* +size+. When called with +len+, a string of +len+ bytes will be returned. * When called with no arguments, this method will return the contents with the
* length of this pointer's +size+.
*
* When called with +len+, a string of +len+ bytes will be returned.
*
* See to_s
*/ */
static VALUE static VALUE
rb_fiddle_ptr_to_str(int argc, VALUE argv[], VALUE self) rb_fiddle_ptr_to_str(int argc, VALUE argv[], VALUE self)
@ -403,7 +424,7 @@ rb_fiddle_ptr_to_str(int argc, VALUE argv[], VALUE self)
* call-seq: inspect * call-seq: inspect
* *
* Returns a string formatted with an easily readable representation of the * Returns a string formatted with an easily readable representation of the
* internal state of the DL::CPtr * internal state of the pointer.
*/ */
static VALUE static VALUE
rb_fiddle_ptr_inspect(VALUE self) rb_fiddle_ptr_inspect(VALUE self)
@ -442,8 +463,9 @@ rb_fiddle_ptr_eql(VALUE self, VALUE other)
* call-seq: * call-seq:
* ptr <=> other => -1, 0, 1, or nil * ptr <=> other => -1, 0, 1, or nil
* *
* Returns -1 if less than, 0 if equal to, 1 if greater than +other+. Returns * Returns -1 if less than, 0 if equal to, 1 if greater than +other+.
* nil if +ptr+ cannot be compared to +other+. *
* Returns nil if +ptr+ cannot be compared to +other+.
*/ */
static VALUE static VALUE
rb_fiddle_ptr_cmp(VALUE self, VALUE other) rb_fiddle_ptr_cmp(VALUE self, VALUE other)
@ -464,7 +486,7 @@ rb_fiddle_ptr_cmp(VALUE self, VALUE other)
* call-seq: * call-seq:
* ptr + n => new cptr * ptr + n => new cptr
* *
* Returns a new DL::CPtr that has been advanced +n+ bytes. * Returns a new pointer instance that has been advanced +n+ bytes.
*/ */
static VALUE static VALUE
rb_fiddle_ptr_plus(VALUE self, VALUE other) rb_fiddle_ptr_plus(VALUE self, VALUE other)
@ -482,7 +504,7 @@ rb_fiddle_ptr_plus(VALUE self, VALUE other)
* call-seq: * call-seq:
* ptr - n => new cptr * ptr - n => new cptr
* *
* Returns a new DL::CPtr that has been moved back +n+ bytes. * Returns a new pointer instance that has been moved back +n+ bytes.
*/ */
static VALUE static VALUE
rb_fiddle_ptr_minus(VALUE self, VALUE other) rb_fiddle_ptr_minus(VALUE self, VALUE other)
@ -501,9 +523,10 @@ rb_fiddle_ptr_minus(VALUE self, VALUE other)
* ptr[index] -> an_integer * ptr[index] -> an_integer
* ptr[start, length] -> a_string * ptr[start, length] -> a_string
* *
* Returns integer stored at _index_. If _start_ and _length_ are given, * Returns integer stored at _index_.
* a string containing the bytes from _start_ of length _length_ will be *
* returned. * If _start_ and _length_ are given, a string containing the bytes from
* _start_ of _length_ will be returned.
*/ */
static VALUE static VALUE
rb_fiddle_ptr_aref(int argc, VALUE argv[], VALUE self) rb_fiddle_ptr_aref(int argc, VALUE argv[], VALUE self)
@ -536,9 +559,11 @@ rb_fiddle_ptr_aref(int argc, VALUE argv[], VALUE self)
* ptr[index] = int -> int * ptr[index] = int -> int
* ptr[start, length] = string or cptr or addr -> string or dl_cptr or addr * ptr[start, length] = string or cptr or addr -> string or dl_cptr or addr
* *
* Set the value at +index+ to +int+. Or, set the memory at +start+ until * Set the value at +index+ to +int+.
* +length+ with the contents of +string+, the memory from +dl_cptr+, or the *
* memory pointed at by the memory address +addr+. * Or, set the memory at +start+ until +length+ with the contents of +string+,
* the memory from +dl_cptr+, or the memory pointed at by the memory address
* +addr+.
*/ */
static VALUE static VALUE
rb_fiddle_ptr_aset(int argc, VALUE argv[], VALUE self) rb_fiddle_ptr_aset(int argc, VALUE argv[], VALUE self)
@ -603,8 +628,8 @@ rb_fiddle_ptr_size_get(VALUE self)
/* /*
* call-seq: * call-seq:
* Fiddle::Pointer.to_ptr(val) => cptr
* Fiddle::Pointer[val] => cptr * Fiddle::Pointer[val] => cptr
* to_ptr(val) => cptr
* *
* Get the underlying pointer for ruby object +val+ and return it as a * Get the underlying pointer for ruby object +val+ and return it as a
* Fiddle::Pointer object. * Fiddle::Pointer object.