Project

General

Profile

Bug #6496 ยป ruby-dl_documentation-20120525.patch

vbatts (Vincent Batts), 05/26/2012 03:31 AM

View differences:

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 = []
    (1-1/1)