summaryrefslogtreecommitdiff
path: root/ext/dl/lib
diff options
context:
space:
mode:
authordrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-05-30 22:48:42 +0000
committerdrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-05-30 22:48:42 +0000
commit2e87e2150e04c37595c02095c410decadfb9977e (patch)
tree476c33a5015665a9bf66aace605ddca10d411ba0 /ext/dl/lib
parentd3a349bbc3d0cd61322b86b500032d75d25a6ec3 (diff)
* ext/dl: Added documentation. Patch by Vincent Batts.
[ruby-trunk - Bug #6496] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35846 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/dl/lib')
-rw-r--r--ext/dl/lib/dl.rb1
-rw-r--r--ext/dl/lib/dl/cparser.rb37
-rw-r--r--ext/dl/lib/dl/import.rb6
-rw-r--r--ext/dl/lib/dl/struct.rb59
4 files changed, 102 insertions, 1 deletions
diff --git a/ext/dl/lib/dl.rb b/ext/dl/lib/dl.rb
index 80d46b685a..b34bb82f41 100644
--- a/ext/dl/lib/dl.rb
+++ b/ext/dl/lib/dl.rb
@@ -6,6 +6,7 @@ rescue LoadError
end
module DL
+ # Returns true if DL is using Fiddle, the libffi wrapper.
def self.fiddle?
Object.const_defined?(:Fiddle)
end
diff --git a/ext/dl/lib/dl/cparser.rb b/ext/dl/lib/dl/cparser.rb
index 7aae9ea4eb..e70e0f1dc1 100644
--- a/ext/dl/lib/dl/cparser.rb
+++ b/ext/dl/lib/dl/cparser.rb
@@ -1,5 +1,13 @@
module DL
+ # Methods for parsing C struct and C prototype signatures.
module CParser
+ # Parses a C struct's members
+ #
+ # Example:
+ #
+ # parse_struct_signature(['int i', 'char c'])
+ # => [[DL::TYPE_INT, DL::TYPE_CHAR], ["i", "c"]]
+ #
def parse_struct_signature(signature, tymap=nil)
if( signature.is_a?(String) )
signature = signature.split(/\s*,\s*/)
@@ -35,6 +43,16 @@ module DL
return tys, mems
end
+ # Parses a C prototype signature
+ #
+ # Example:
+ #
+ # include DL::CParser
+ # => Object
+ #
+ # parse_signature('double sum(double, double)')
+ # => ["sum", DL::TYPE_DOUBLE, [DL::TYPE_DOUBLE, DL::TYPE_DOUBLE]]
+ #
def parse_signature(signature, tymap=nil)
tymap ||= {}
signature = signature.gsub(/\s+/, " ").strip
@@ -56,6 +74,25 @@ module DL
end
end
+ # Given a String of C type +ty+, return the corresponding DL constant.
+ #
+ # +ty+ can also accept an Array of C type Strings, and will 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:
+ #
+ # parse_ctype('int')
+ # => DL::TYPE_INT
+ #
+ # parse_ctype('double')
+ # => DL::TYPE_DOUBLE
+ #
+ # parse_ctype('unsigned char')
+ # => -DL::TYPE_CHAR
+ #
def parse_ctype(ty, tymap=nil)
tymap ||= {}
case ty
diff --git a/ext/dl/lib/dl/import.rb b/ext/dl/lib/dl/import.rb
index eec65cdfd6..a318430b73 100644
--- a/ext/dl/lib/dl/import.rb
+++ b/ext/dl/lib/dl/import.rb
@@ -179,11 +179,17 @@ module DL
f
end
+ # Creates a class to wrap the C struct described by +signature+.
+ #
+ # MyStruct = struct ['int i', 'char c']
def struct(signature)
tys, mems = parse_struct_signature(signature, @type_alias)
DL::CStructBuilder.create(CStruct, tys, mems)
end
+ # Creates a class to wrap the C union described by +signature+.
+ #
+ # MyUnion = union ['int i', 'char c']
def union(signature)
tys, mems = parse_struct_signature(signature, @type_alias)
DL::CStructBuilder.create(CUnion, tys, mems)
diff --git a/ext/dl/lib/dl/struct.rb b/ext/dl/lib/dl/struct.rb
index b8becca6b6..27f6b42fd2 100644
--- a/ext/dl/lib/dl/struct.rb
+++ b/ext/dl/lib/dl/struct.rb
@@ -2,19 +2,50 @@ require 'dl'
require 'dl/pack.rb'
module DL
+ # C struct shell
class CStruct
+ # accessor to DL::CStructEntity
def CStruct.entity_class()
CStructEntity
end
end
+ # C union shell
class CUnion
+ # accessor to DL::CUnionEntity
def CUnion.entity_class()
CUnionEntity
end
end
+ # Used to construct C classes (CUnion, CStruct, etc)
+ #
+ # DL::Importer#struct and DL::Importer#union wrap this functionality in an
+ # easy-to-use manner.
module CStructBuilder
+ # Construct a new class given a C:
+ # * class +klass+ (CUnion, CStruct, or other that provide an
+ # #entity_class)
+ # * +types+ (DL:TYPE_INT, DL::TYPE_SIZE_T, etc., see the C types
+ # constants)
+ # * corresponding +members+
+ #
+ # DL::Importer#struct and DL::Importer#union wrap this functionality in an
+ # easy-to-use manner.
+ #
+ # Example:
+ #
+ # require 'dl/struct'
+ # require 'dl/cparser'
+ #
+ # include DL::CParser
+ #
+ # types, members = parse_struct_signature(['int i','char c'])
+ #
+ # MyStruct = DL::CStructBuilder.create(CUnion, types, members)
+ #
+ # obj = MyStruct.allocate
+ #
def create(klass, types, members)
new_class = Class.new(klass){
define_method(:initialize){|addr|
@@ -43,15 +74,23 @@ module DL
module_function :create
end
+ # A C struct wrapper
class CStructEntity < CPtr
include PackInfo
include ValueUtil
+ # Allocates a C struct the +types+ provided. The C function +func+ is
+ # called when the instance is garbage collected.
def CStructEntity.malloc(types, func = nil)
addr = DL.malloc(CStructEntity.size(types))
CStructEntity.new(addr, types, func)
end
+ # Given +types+, returns the offset for the packed sizes of those types
+ #
+ # DL::CStructEntity.size([DL::TYPE_DOUBLE, DL::TYPE_INT, DL::TYPE_CHAR,
+ # DL::TYPE_VOIDP])
+ # => 24
def CStructEntity.size(types)
offset = 0
max_align = 0
@@ -76,15 +115,22 @@ module DL
offset
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.
+ #
+ # See also DL::CPtr.new
def initialize(addr, types, func = nil)
set_ctypes(types)
super(addr, @size, func)
end
+ # Set the names of the +members+ in this C struct
def assign_names(members)
@members = members
end
+ # Given +types+, calculate the offsets and sizes for the types in the
+ # struct.
def set_ctypes(types)
@ctypes = types
@offset = []
@@ -112,6 +158,7 @@ module DL
@size = offset
end
+ # Fetch struct member +name+
def [](name)
idx = @members.index(name)
if( idx.nil? )
@@ -145,6 +192,7 @@ module DL
end
end
+ # Set struct member +name+, to value +val+
def []=(name, val)
idx = @members.index(name)
if( idx.nil? )
@@ -164,19 +212,27 @@ module DL
end
end
- def to_s()
+ def to_s() # :nodoc:
super(@size)
end
end
+ # A C union wrapper
class CUnionEntity < CStructEntity
include PackInfo
+ # Allocates a C union the +types+ provided. The C function +func+ is
+ # called when the instance is garbage collected.
def CUnionEntity.malloc(types, func=nil)
addr = DL.malloc(CUnionEntity.size(types))
CUnionEntity.new(addr, types, func)
end
+ # Given +types+, returns the size needed for the union.
+ #
+ # DL::CUnionEntity.size([DL::TYPE_DOUBLE, DL::TYPE_INT, DL::TYPE_CHAR,
+ # DL::TYPE_VOIDP])
+ # => 8
def CUnionEntity.size(types)
size = 0
types.each_with_index{|t,i|
@@ -191,6 +247,7 @@ module DL
}
end
+ # Given +types+, calculate the necessary offset and for each union member
def set_ctypes(types)
@ctypes = types
@offset = []