Bug #6496 ยป ruby-dl_documentation-20120525.patch
ext/dl/dl.c | ||
---|---|---|
#endif
|
||
#define DLTYPE_UINTPTR_T (-DLTYPE_INTPTR_T)
|
||
/*
|
||
* call-seq: DL.dlopen(so_lib)
|
||
*
|
||
* == Description
|
||
* An interface to the dynamic linking loader
|
||
*
|
||
* This is a shortcut to DL::Handle.new and takes the same arguments.
|
||
*
|
||
* == Example
|
||
* libc_so = "/lib64/libc.so.6"
|
||
* => "/lib64/libc.so.6"
|
||
* libc = DL.dlopen(libc_so)
|
||
* => #<DL::Handle:0x00000000e05b00>
|
||
*/
|
||
VALUE
|
||
rb_dl_dlopen(int argc, VALUE argv[], VALUE self)
|
||
{
|
||
... | ... | |
}
|
||
/*
|
||
* call-seq: DL.malloc
|
||
* call-seq: DL.malloc(size)
|
||
*
|
||
* Allocate +size+ bytes of memory and return the integer memory address
|
||
* for the allocated memory.
|
||
... | ... | |
return Qnil;
|
||
}
|
||
/*
|
||
* call-seq: DL.dlunwrap(addr)
|
||
*
|
||
* returns the hexdecimal representation of a memory pointer address +addr+
|
||
*
|
||
* == Example
|
||
* lib = DL.dlopen('/lib64/libc-2.15.so')
|
||
* => #<DL::Handle:0x00000001342460>
|
||
* lib['strcpy'].to_s(16)
|
||
* => "7f59de6dd240"
|
||
* DL.dlunwrap(DL.dlwrap(lib['strcpy'].to_s(16)))
|
||
* => "7f59de6dd240"
|
||
*/
|
||
VALUE
|
||
rb_dl_ptr2value(VALUE self, VALUE addr)
|
||
{
|
||
... | ... | |
return (VALUE)NUM2PTR(addr);
|
||
}
|
||
/*
|
||
* call-seq: DL.dlwrap(val)
|
||
*
|
||
* returns a memory pointer of a function's hexdecimal address location +val+
|
||
*
|
||
* == Example
|
||
* lib = DL.dlopen('/lib64/libc-2.15.so')
|
||
* => #<DL::Handle:0x00000001342460>
|
||
* DL.dlwrap(lib['strcpy'].to_s(16))
|
||
* => 25522520
|
||
*/
|
||
VALUE
|
||
rb_dl_value2ptr(VALUE self, VALUE val)
|
||
{
|
||
... | ... | |
/* Document-const: SIZEOF_UINTPTR_T
|
||
*
|
||
* size of a intptr_t
|
||
* size of a uintptr_t
|
||
*/
|
||
rb_define_const(rb_mDL, "SIZEOF_UINTPTR_T", INT2NUM(sizeof(uintptr_t)));
|
||
ext/dl/lib/dl.rb | ||
---|---|---|
end
|
||
module DL
|
||
# returns a boolean, of whether Fiddle is defined
|
||
def self.fiddle?
|
||
Object.const_defined?(:Fiddle)
|
||
end
|
ext/dl/lib/dl/cparser.rb | ||
---|---|---|
module DL
|
||
# To be used as a mixin.
|
||
module CParser
|
||
# parses a C struct's members
|
||
#
|
||
# == Example
|
||
# parse_struct_signature(['int i', 'char c'])
|
||
# => [[4, 2], ["i", "c"]]
|
||
#
|
||
def parse_struct_signature(signature, tymap=nil)
|
||
if( signature.is_a?(String) )
|
||
signature = signature.split(/\s*,\s*/)
|
||
... | ... | |
return tys, mems
|
||
end
|
||
# parses a C prototype signature
|
||
#
|
||
# == Example
|
||
# include DL::CParser
|
||
# => Object
|
||
# parse_signature('double sum(double, double)')
|
||
# => ["sum", 8, [8, 8]]
|
||
#
|
||
def parse_signature(signature, tymap=nil)
|
||
tymap ||= {}
|
||
signature = signature.gsub(/\s+/, " ").strip
|
||
... | ... | |
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')
|
||
# => 4
|
||
# parse_ctype('double')
|
||
# => 8
|
||
# parse_ctype('unsigned char')
|
||
# => -2
|
||
#
|
||
def parse_ctype(ty, tymap=nil)
|
||
tymap ||= {}
|
||
case ty
|
ext/dl/lib/dl/import.rb | ||
---|---|---|
f
|
||
end
|
||
# Given a C struct prototype +signature+, construct a DL::CStruct
|
||
def struct(signature)
|
||
tys, mems = parse_struct_signature(signature, @type_alias)
|
||
DL::CStructBuilder.create(CStruct, tys, mems)
|
||
end
|
||
# Given a C union prototype +signature+, construct a DL::CUnion
|
||
def union(signature)
|
||
tys, mems = parse_struct_signature(signature, @type_alias)
|
||
DL::CStructBuilder.create(CUnion, tys, mems)
|
ext/dl/lib/dl/struct.rb | ||
---|---|---|
require 'dl/pack.rb'
|
||
module DL
|
||
# C struct shell
|
||
class CStruct
|
||
# accesor to DL::CStructEntity
|
||
def CStruct.entity_class()
|
||
CStructEntity
|
||
end
|
||
end
|
||
# C union shell
|
||
class CUnion
|
||
# accesor to DL::CUnionEntity
|
||
def CUnion.entity_class()
|
||
CUnionEntity
|
||
end
|
||
end
|
||
# Used to construct C classes (CUnion, CStruct, etc)
|
||
module CStructBuilder
|
||
# 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+
|
||
# Construct a new class
|
||
#
|
||
# == Example
|
||
# require 'dl/struct'
|
||
# => true
|
||
# require 'dl/cparser'
|
||
# => true
|
||
# include DL::CParser
|
||
# => Object
|
||
# types, members = parse_struct_signature(['int i','char c'])
|
||
# => [[4, 2], ["i", "c"]]
|
||
# mystruct = DL::CStructBuilder.create(CUnion, types, members)
|
||
# => #<Class:0x00000001413ab0>
|
||
#
|
||
def create(klass, types, members)
|
||
new_class = Class.new(klass){
|
||
define_method(:initialize){|addr|
|
||
... | ... | |
module_function :create
|
||
end
|
||
# Subclasses DL::CPtr
|
||
class CStructEntity < CPtr
|
||
include PackInfo
|
||
include ValueUtil
|
||
# Uses DL.malloc, to memory allocate for all +types+ provided
|
||
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
|
||
... | ... | |
offset
|
||
end
|
||
# Creates a new pointer to address +addr+
|
||
# with C +types
|
||
#
|
||
# Option 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 necessary offset and size
|
||
def set_ctypes(types)
|
||
@ctypes = types
|
||
@offset = []
|
||
... | ... | |
@size = offset
|
||
end
|
||
# fetch member +name+
|
||
def [](name)
|
||
idx = @members.index(name)
|
||
if( idx.nil? )
|
||
... | ... | |
end
|
||
end
|
||
# set member +name+, to value +val
|
||
def []=(name, val)
|
||
idx = @members.index(name)
|
||
if( idx.nil? )
|
||
... | ... | |
end
|
||
end
|
||
# display as string
|
||
def to_s()
|
||
super(@size)
|
||
end
|
||
end
|
||
# Subclasses DL::CStructEntity
|
||
class CUnionEntity < CStructEntity
|
||
include PackInfo
|
||
# Uses DL.malloc, to memory allocate for all +types+ provided
|
||
def CUnionEntity.malloc(types, func=nil)
|
||
addr = DL.malloc(CUnionEntity.size(types))
|
||
CUnionEntity.new(addr, types, func)
|
||
end
|
||
# given +types+, return the packed size information for those types
|
||
#
|
||
# DL::CUnionEntity.size([DL::TYPE_DOUBLE, DL::TYPE_INT, DL::TYPE_CHAR, DL::TYPE_VOIDP])
|
||
# => [8, 4, 2, 1]
|
||
#
|
||
def CUnionEntity.size(types)
|
||
size = 0
|
||
types.each_with_index{|t,i|
|
||
... | ... | |
}
|
||
end
|
||
# given +types+, calculate the necessary offset and size
|
||
def set_ctypes(types)
|
||
@ctypes = types
|
||
@offset = []
|