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 = []
|
||