summaryrefslogtreecommitdiff
path: root/ext/fiddle
diff options
context:
space:
mode:
authorzzak <zzak@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-11-28 02:08:39 +0000
committerzzak <zzak@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-11-28 02:08:39 +0000
commit4ed6a88b74be65894b580dba81e7b8e3e8b0c3ce (patch)
tree175e78cc10375e9091a6e712f4d1f51a42856608 /ext/fiddle
parent0700a9113f94a82d786271bc44140691d47f6bac (diff)
* ext/fiddle/closure.c: Documentation for Fiddle
* ext/fiddle/lib/fiddle/import.rb: ditto * ext/fiddle/lib/fiddle/value.rb: ditto * ext/fiddle/lib/fiddle/pack.rb: ditto * ext/fiddle/lib/fiddle/cparser.rb: ditto * ext/fiddle/lib/fiddle/struct.rb: ditto * ext/fiddle/lib/fiddle/function.rb: ditto git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37917 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/fiddle')
-rw-r--r--ext/fiddle/closure.c2
-rw-r--r--ext/fiddle/lib/fiddle/cparser.rb40
-rw-r--r--ext/fiddle/lib/fiddle/function.rb1
-rw-r--r--ext/fiddle/lib/fiddle/import.rb71
-rw-r--r--ext/fiddle/lib/fiddle/pack.rb4
-rw-r--r--ext/fiddle/lib/fiddle/struct.rb49
-rw-r--r--ext/fiddle/lib/fiddle/value.rb2
7 files changed, 129 insertions, 40 deletions
diff --git a/ext/fiddle/closure.c b/ext/fiddle/closure.c
index 3c6dccf51b..6690b87c25 100644
--- a/ext/fiddle/closure.c
+++ b/ext/fiddle/closure.c
@@ -289,7 +289,7 @@ Init_fiddle_closure()
* Construct a new Closure object.
*
* * +ret+ is the C type to be returned
- * * +args+ are passed the callback
+ * * +args+is an Array of arguments, passed to the callback function
* * +abi+ is the abi of the closure
*
* If there is an error in preparing the ffi_cif or ffi_prep_closure,
diff --git a/ext/fiddle/lib/fiddle/cparser.rb b/ext/fiddle/lib/fiddle/cparser.rb
index ede88ae668..43fb184a12 100644
--- a/ext/fiddle/lib/fiddle/cparser.rb
+++ b/ext/fiddle/lib/fiddle/cparser.rb
@@ -1,12 +1,25 @@
module Fiddle
- # Methods for parsing C struct and C prototype signatures.
+ # A mixin that provides methods for parsing C struct and prototype signatures.
+ #
+ # == Example
+ # require 'fiddle/import'
+ #
+ # include Fiddle::CParser
+ # #=> Object
+ #
+ # parse_ctype('int increment(int)')
+ # #=> ["increment", Fiddle::TYPE_INT, [Fiddle::TYPE_INT]]
+ #
module CParser
# Parses a C struct's members
#
# Example:
#
+ # include Fiddle::CParser
+ # #=> Object
+ #
# parse_struct_signature(['int i', 'char c'])
- # => [[Fiddle::TYPE_INT, Fiddle::TYPE_CHAR], ["i", "c"]]
+ # #=> [[Fiddle::TYPE_INT, Fiddle::TYPE_CHAR], ["i", "c"]]
#
def parse_struct_signature(signature, tymap=nil)
if( signature.is_a?(String) )
@@ -45,13 +58,17 @@ module Fiddle
# Parses a C prototype signature
#
+ # If Hash +tymap+ is provided, the return value and the arguments from the
+ # +signature+ are expected to be keys, and the value will be the C type to
+ # be looked up.
+ #
# Example:
#
# include Fiddle::CParser
- # => Object
+ # #=> Object
#
# parse_signature('double sum(double, double)')
- # => ["sum", Fiddle::TYPE_DOUBLE, [Fiddle::TYPE_DOUBLE, Fiddle::TYPE_DOUBLE]]
+ # #=> ["sum", Fiddle::TYPE_DOUBLE, [Fiddle::TYPE_DOUBLE, Fiddle::TYPE_DOUBLE]]
#
def parse_signature(signature, tymap=nil)
tymap ||= {}
@@ -74,24 +91,27 @@ module Fiddle
end
end
- # Given a String of C type +ty+, return the corresponding DL constant.
+ # Given a String of C type +ty+, returns the corresponding Fiddle constant.
#
- # +ty+ can also accept an Array of C type Strings, and will returned in a
- # corresponding Array.
+ # +ty+ can also accept an Array of C type Strings, and will be returned in
+ # a corresponding Array.
#
# If Hash +tymap+ is provided, +ty+ is expected to be the key, and the
# value will be the C type to be looked up.
#
# Example:
#
+ # include Fiddle::CParser
+ # #=> Object
+ #
# parse_ctype('int')
- # => Fiddle::TYPE_INT
+ # #=> Fiddle::TYPE_INT
#
# parse_ctype('double')
- # => Fiddle::TYPE_DOUBLE
+ # #=> Fiddle::TYPE_DOUBLE
#
# parse_ctype('unsigned char')
- # => -Fiddle::TYPE_CHAR
+ # #=> -Fiddle::TYPE_CHAR
#
def parse_ctype(ty, tymap=nil)
tymap ||= {}
diff --git a/ext/fiddle/lib/fiddle/function.rb b/ext/fiddle/lib/fiddle/function.rb
index f4d41e6a82..07a072e021 100644
--- a/ext/fiddle/lib/fiddle/function.rb
+++ b/ext/fiddle/lib/fiddle/function.rb
@@ -6,6 +6,7 @@ module Fiddle
# The address of this function
attr_reader :ptr
+ # The integer memory location of this function
def to_i
ptr.to_i
end
diff --git a/ext/fiddle/lib/fiddle/import.rb b/ext/fiddle/lib/fiddle/import.rb
index 10b4fad2b5..ba0f716a9a 100644
--- a/ext/fiddle/lib/fiddle/import.rb
+++ b/ext/fiddle/lib/fiddle/import.rb
@@ -3,15 +3,25 @@ require 'fiddle/struct'
require 'fiddle/cparser'
module Fiddle
+
+ # Used internally by Fiddle::Importer
class CompositeHandler
+ # Create a new handler with the open +handlers+
+ #
+ # Used internally by Fiddle::Importer.dlload
def initialize(handlers)
@handlers = handlers
end
+ # Array of the currently loaded libraries.
def handlers()
@handlers
end
+ # Returns the address as an Integer from any handlers with the function
+ # named +symbol+.
+ #
+ # Raises a DLError if the handle is closed.
def sym(symbol)
@handlers.each{|handle|
if( handle )
@@ -25,32 +35,40 @@ module Fiddle
return nil
end
+ # See Fiddle::CompositeHandler.sym
def [](symbol)
sym(symbol)
end
end
- # DL::Importer includes the means to dynamically load libraries and build
+ # A DSL that provides the means to dynamically load libraries and build
# modules around them including calling extern functions within the C
# library that has been loaded.
#
# == Example
#
- # require 'dl'
- # require 'dl/import'
+ # require 'fiddle'
+ # require 'fiddle/import'
#
# module LibSum
- # extend DL::Importer
+ # extend Fiddle::Importer
# dlload './libsum.so'
# extern 'double sum(double*, int)'
# extern 'double split(double)'
# end
- #
+ #
module Importer
include Fiddle
include CParser
extend Importer
+ # Creates an array of handlers for the given +libs+, can be an instance of
+ # Fiddle::Handle, Fiddle::Importer, or will create a new istance of
+ # Fiddle::Handle using Fiddle.dlopen
+ #
+ # Raises a DLError if the library cannot be loaded.
+ #
+ # See Fiddle.dlopen
def dlload(*libs)
handles = libs.collect{|lib|
case lib
@@ -73,10 +91,13 @@ module Fiddle
@type_alias = {}
end
+ # Sets the type alias for +alias_type+ as +orig_type+
def typealias(alias_type, orig_type)
@type_alias[alias_type] = orig_type
end
+ # Returns the sizeof +ty+, using Fiddle::Importer.parse_ctype to determine
+ # the C type and the appropriate Fiddle constant.
def sizeof(ty)
case ty
when String
@@ -126,6 +147,7 @@ module Fiddle
end
private :parse_bind_options
+ # Creates a global method from the given C +signature+.
def extern(signature, *opts)
symname, ctype, argtype = parse_signature(signature, @type_alias)
opt = parse_bind_options(opts)
@@ -148,6 +170,8 @@ module Fiddle
f
end
+ # Creates a global method from the given C +signature+ using the given
+ # +opts+ as bind parameters with the given block.
def bind(signature, *opts, &blk)
name, ctype, argtype = parse_signature(signature, @type_alias)
h = parse_bind_options(opts)
@@ -190,10 +214,15 @@ module Fiddle
Fiddle::CStructBuilder.create(CUnion, tys, mems)
end
+ # Returns the function mapped to +name+, that was created by either
+ # Fiddle::Importer.extern or Fiddle::Importer.bind
def [](name)
@func_map[name]
end
+ # Creates a class to wrap the C struct with the value +ty+
+ #
+ # See also Fiddle::Importer.struct
def create_value(ty, val=nil)
s = struct([ty + " value"])
ptr = s.malloc()
@@ -204,16 +233,28 @@ module Fiddle
end
alias value create_value
+ # Returns a new instance of the C struct with the value +ty+ at the +addr+
+ # address.
def import_value(ty, addr)
s = struct([ty + " value"])
ptr = s.new(addr)
return ptr
end
+
+ # The Fiddle::CompositeHandler instance
+ #
+ # Will raise an error if no handlers are open.
def handler
@handler or raise "call dlload before importing symbols and functions"
end
+ # Returns a new Fiddle::Pointer instance at the memory address of the given
+ # +name+ symbol.
+ #
+ # Raises a DLError if the +name+ doesn't exist.
+ #
+ # See Fiddle::CompositeHandler.sym and Fiddle::Handle.sym
def import_symbol(name)
addr = handler.sym(name)
if( !addr )
@@ -222,6 +263,18 @@ module Fiddle
Pointer.new(addr)
end
+ # Returns a new Fiddle::Function instance at the memory address of the given
+ # +name+ function.
+ #
+ # Raises a DLError if the +name+ doesn't exist.
+ #
+ # * +argtype+ is an Array of arguments, passed to the +name+ function.
+ # * +ctype+ is the return type of the function
+ # * +call_type+ is the ABI of the function
+ #
+ # See also Fiddle:Function.new
+ #
+ # See Fiddle::CompositeHandler.sym and Fiddle::Handler.sym
def import_function(name, ctype, argtype, call_type = nil)
addr = handler.sym(name)
if( !addr )
@@ -230,6 +283,14 @@ module Fiddle
Function.new(addr, argtype, ctype, call_type)
end
+ # Returns a new closure wrapper for the +name+ function.
+ #
+ # * +ctype+ is the return type of the function
+ # * +argtype+ is an Array of arguments, passed to the callback function
+ # * +call_type+ is the abi of the closure
+ # * +block+ is passed to the callback
+ #
+ # See Fiddle::Closure
def bind_function(name, ctype, argtype, call_type = nil, &block)
closure = Class.new(Fiddle::Closure) {
define_method(:call, block)
diff --git a/ext/fiddle/lib/fiddle/pack.rb b/ext/fiddle/lib/fiddle/pack.rb
index f406d374f9..e4e9542cc0 100644
--- a/ext/fiddle/lib/fiddle/pack.rb
+++ b/ext/fiddle/lib/fiddle/pack.rb
@@ -1,7 +1,7 @@
require 'fiddle'
module Fiddle
- module PackInfo
+ module PackInfo # :nodoc: all
ALIGN_MAP = {
TYPE_VOIDP => ALIGN_VOIDP,
TYPE_CHAR => ALIGN_CHAR,
@@ -60,7 +60,7 @@ module Fiddle
module_function :align
end
- class Packer
+ class Packer # :nodoc: all
include PackInfo
def self.[](*types)
diff --git a/ext/fiddle/lib/fiddle/struct.rb b/ext/fiddle/lib/fiddle/struct.rb
index 043b3885b3..5a70699bf3 100644
--- a/ext/fiddle/lib/fiddle/struct.rb
+++ b/ext/fiddle/lib/fiddle/struct.rb
@@ -36,14 +36,14 @@ module Fiddle
#
# Example:
#
- # require 'dl/struct'
- # require 'dl/cparser'
+ # require 'fiddle/struct'
+ # require 'fiddle/cparser'
#
# include Fiddle::CParser
#
# types, members = parse_struct_signature(['int i','char c'])
#
- # MyStruct = Fiddle::CStructBuilder.create(CUnion, types, members)
+ # MyStruct = Fiddle::CStructBuilder.create(Fiddle::CUnion, types, members)
#
# obj = MyStruct.allocate
#
@@ -80,18 +80,21 @@ module Fiddle
include PackInfo
include ValueUtil
- # Allocates a C struct the +types+ provided. The C function +func+ is
- # called when the instance is garbage collected.
+ # Allocates a C struct with the +types+ provided.
+ #
+ # When the instance is garbage collected, the C function +func+ is called.
def CStructEntity.malloc(types, func = nil)
addr = Fiddle.malloc(CStructEntity.size(types))
CStructEntity.new(addr, types, func)
end
- # Given +types+, returns the offset for the packed sizes of those types
+ # Returns the offset for the packed sizes for the given +types+.
#
- # Fiddle::CStructEntity.size([Fiddle::TYPE_DOUBLE, Fiddle::TYPE_INT, Fiddle::TYPE_CHAR,
- # Fiddle::TYPE_VOIDP])
- # => 24
+ # Fiddle::CStructEntity.size(
+ # [ Fiddle::TYPE_DOUBLE,
+ # Fiddle::TYPE_INT,
+ # Fiddle::TYPE_CHAR,
+ # Fiddle::TYPE_VOIDP ]) #=> 24
def CStructEntity.size(types)
offset = 0
@@ -108,10 +111,11 @@ module Fiddle
PackInfo.align(offset, max_align)
end
- # Wraps the C pointer +addr+ as a C struct with the given +types+. The C
- # function +func+ is called when the instance is garbage collected.
+ # Wraps the C pointer +addr+ as a C struct with the given +types+.
+ #
+ # When the instance is garbage collected, the C function +func+ is called.
#
- # See also Fiddle::CPtr.new
+ # See also Fiddle::Pointer.new
def initialize(addr, types, func = nil)
set_ctypes(types)
super(addr, @size, func)
@@ -122,8 +126,7 @@ module Fiddle
@members = members
end
- # Given +types+, calculate the offsets and sizes for the types in the
- # struct.
+ # Calculates the offsets and sizes for the given +types+ in the struct.
def set_ctypes(types)
@ctypes = types
@offset = []
@@ -207,25 +210,29 @@ module Fiddle
class CUnionEntity < CStructEntity
include PackInfo
- # Allocates a C union the +types+ provided. The C function +func+ is
- # called when the instance is garbage collected.
+ # Allocates a C union the +types+ provided.
+ #
+ # When the instance is garbage collected, the C function +func+ is called.
def CUnionEntity.malloc(types, func=nil)
addr = Fiddle.malloc(CUnionEntity.size(types))
CUnionEntity.new(addr, types, func)
end
- # Given +types+, returns the size needed for the union.
+ # Returns the size needed for the union with the given +types+.
#
- # Fiddle::CUnionEntity.size([Fiddle::TYPE_DOUBLE, Fiddle::TYPE_INT, Fiddle::TYPE_CHAR,
- # Fiddle::TYPE_VOIDP])
- # => 8
+ # Fiddle::CUnionEntity.size(
+ # [ Fiddle::TYPE_DOUBLE,
+ # Fiddle::TYPE_INT,
+ # Fiddle::TYPE_CHAR,
+ # Fiddle::TYPE_VOIDP ]) #=> 8
def CUnionEntity.size(types)
types.map { |type, count = 1|
PackInfo::SIZE_MAP[type] * count
}.max
end
- # Given +types+, calculate the necessary offset and for each union member
+ # Calculate the necessary offset and for each union member with the given
+ # +types+
def set_ctypes(types)
@ctypes = types
@offset = Array.new(types.length, 0)
diff --git a/ext/fiddle/lib/fiddle/value.rb b/ext/fiddle/lib/fiddle/value.rb
index 0849e4ac35..d1d02cccf5 100644
--- a/ext/fiddle/lib/fiddle/value.rb
+++ b/ext/fiddle/lib/fiddle/value.rb
@@ -1,7 +1,7 @@
require 'fiddle'
module Fiddle
- module ValueUtil
+ module ValueUtil #:nodoc: all
def unsigned_value(val, ty)
case ty.abs
when TYPE_CHAR