附加库

包含FIPS PUB 180-1中提到的NIST (the US' National Institute of Standards and Technology) 的 SHA-1 Secure Hash Algorithm的类。
超类:

  * Digest::Base

类方法:

Digest::SHA1.new([str])
Digest::SHA1.digest(str)
Digest::SHA1.hexdigest(str)

  请参考Digest::Base页面。

方法:

dup
clone
digest
hexdigest
to_s
update(str)
self << str
self == md
self == str

  请参考Digest::Base页面。
包含FIPS PUB 180-2中提到的NIST (the US' National Institute of Standards and Technology) 的 SHA-256 Secure Hash Algorithm的类。
超类:

  * Digest::Base

类方法:

Digest::SHA256.new([str])
Digest::SHA256.digest(str)
Digest::SHA256.hexdigest(str)

  请参考Digest::Base页面。

方法:

dup
clone
digest
hexdigest
to_s
update(str)
self << str
self == md
self == str

  请参考Digest::Base页面。
包含FIPS PUB 180-2中提到的NIST (the US' National Institute of Standards and Technology) 的 SHA-384 Secure Hash Algorithm的类。
超类:

  * Digest::Base

类方法:

Digest::SHA384.new([str])
Digest::SHA384.digest(str)
Digest::SHA384.hexdigest(str)

  请参考Digest::Base页面。

方法:

dup
clone
digest
hexdigest
to_s
update(str)
self << str
self == md
self == str

  请参考Digest::Base页面。
包含FIPS PUB 180-2中提到的NIST (the US' National Institute of Standards and Technology) 的 SHA-512 Secure Hash Algorithm的类。
超类:

  * Digest::Base

类方法:

Digest::SHA512.new([str])
Digest::SHA512.digest(str)
Digest::SHA512.hexdigest(str)

  请参考Digest::Base页面。

方法:

dup
clone
digest
hexdigest
to_s
update(str)
self << str
self == md
self == str

  请参考Digest::Base页面。
Ruby/DL为UNIX的dlopen(3)或Windows的LoadLibrary()等dynamic linker提供接口。
Using Ruby/DL

通常使用dl/import.rb的 DL::Importable 模块。其中包含了用来访问库函数的高水准函数。在扩展某模块时, 要像下面这样使用 DL::Importable 。

require "dl/import"
module LIBC
 extend DL::Importable
end

此后,就可以使用该模块的dlload和extern方法了。可以像下面这样, 使用dlload来加载库, 然后分别对库函数使用extern来定义封装方法。

module LIBC
 extend DL::Importable
 dlload "libc.so.6","libm.so.6"
 extern "int strlen(char*)"
end
# Note that we should not include the module LIBC from some reason.

使用了LIBC.strlen之后, 就可以使用库函数strlen()了. 若给出的函数名的首字母是大写的话, 所定义的函数名的首字母就是小写.

可以像下例这样, 使用了dl/struct.rb中定义的struct或union函数之后, 就可以生成结构体或共用体的映像(memory image)了.

require "dl/import"
require "dl/struct"
module LIBC
 extend DL::Importable
 Timeval = struct [   # define timeval structure.
  "long tv_sec",
  "long tv_uses",
 ]
end
val = LIBC::Timeval.malloc # allocate memory.

请注意, 上例中分配内存时使用的是LIBC::Timeval.malloc, 而不是LIBC::Timeval.new。LIBC::Timeval.new的作用是将已生成的PtrData 对象封装起来。

可以像下例中这样, 使用模块函数callback来定义回叫(callback)。

module Foo
 extend DL::Importable
 def my_comp(str1,str2)
  str1 <=> str2
 end
 COMPARE = callback "int my_comp(char*,char*)"
end

这里的Foo::COMPARE是用来启动my_comp方法的Symbol 对象。

DL::Importable 模块非常易用。但有时也不得不直接使用像dlsym()这样的低级函数。这时应该使用DL 模块的函数。我们将在下节中谈到这个问题。
DL module

模块DL由3个包含若干模块函数和常数的类构成。Symbol类相当于可调用的符号。PtrData类用来表示像C的指针这样的内存块。由Handle类生成的对象负责操作已打开的库。
Constants

  * RTLD_GLOBAL
  * RTLD_LAZY
  * RTLD_NOW
  * MAX_ARG
  * MAX_CBARG
  * MAX_CBENT

Functions

  * handle = dlopen(lib){|handle| ... }
    o 等价于`Handle.new(lib)'。
  * sym = set_callback(cbtype, entry){|args| ... }
  * sym = set_callback(cbtype, entry, proc)
    o 生成用来调用proc或指定块的entry-th pre-defined function。entry-th pre-defined function由cbtype以及entry来指定。cbtype是回叫(callback)的原型。关于cbtype的问题,请参考`Type specifiers' 。
  * sym = get_callback(cbtype, entry)
    o 返回上面的`set_callback'函数给出的Proc 对象。
  * ptr = malloc(size, [free = nil])
    o 分配出size字节的内存空间, 以ptr的形式返回PtrData 对象。
  * ptr = strdup(str)
    o 返回PtrData对象, 它对应于指向str字符串的新拷贝的指针。
  * size = sizeof(type)
    o

    返回类型的大小。`sizeof("C") + sizeof("L")'并不得等价于`sizeof("CL")'。一般认为后者会为 `struct foo { char c; long l; }'返回足够的大小, 而该大小可能有别于C语言的`sizeof(foo)'的返回值。

    (译注: sizeof方法会自己考虑alignment问题从而决定类型的大小, 这可能有别与C语言中的相关方法)

    (译注: 可以像sizeof("L3")这样在类型后面添加数字. 请参考Type specifiers来了解可用的类型)

Handle class

  * handle = Handle.new(lib){|handle| ... }
    o 打开lib库, 返回Handle对象--handle。若指定了块的话, (译注:将打开的handle传给块参数, 再执行块的内容) 块运行结束后会自动关闭handle。
  * Handle#close
    o 关闭上面的Handle.new(lib)打开的handle。
  * sym = Handle#sym(func, prototype = "0"), sym = Handle#[func, prototype = nil]
    o 取得指向func函数(译注:或许是全局变量?)的指针, 返回Symbol对象或DataPtr对象。prototype是由类型分类符构成的字符串,它表示函数的原型。请参考Type specifiers。

Symbol class

  * sym = Symbol.new(addr, type = nil, name = nil)
    o 若type非nil, 则生成类型为type的Symbol对象--sym 。addr是地址。若type为nil, 则返回DataPtr 对象。
  * Symbol::char2type(char)
    o 取得与类型相应的字符char, 返回C语言的类型分类。
  * str = Symbol#proto()
    o 返回函数的原型。
  * str = Symbol#name()
    o 返回函数名。
  * str = Symbol#cproto(), str = Symbol#to_s()
    o 返回C语言形式的原型。
  * str = Symbol#inspect()
    o 返回易读的字符串(译注:意译)。
  * r,rs = Symbol#call(arg1,arg2,...,argN), r,rs = Symbol#[](arg1,arg2,...,argN)
    o 以参数arg1, arg2, ... argN来调用函数。结果由返回值r以及参数rs构成。rs是数组。
  * ptr = Symbol#to_ptr
    o 返回对应的PtrData对象--ptr 。

PtrData class

  * ptr = PtrData.new(addr, [size = 0, free = nil])
    o 返回PtrData对象, 它对应于指向地址addr的指针。GC使用free函数来释放内存空间。
  * PtrData#free=(sym)
    o 若指定了符号对象sym时, GC使用对应于sym的函数来释放内存空间。
  * sym = PtrData#free
    o 返回GC释放内存时使用的符号对象sym 。通常情况下, sym 由 `PtrData#free='或`PtrData.new'来设定。
  * size = PtrData#size, PtrData#size=(size)
    o 设定并取得大小为size的内存空间。
  * ary = PtrData#to_a(type, [size])
    o 返回由type指定的类型的数组。type可以是 'S','P','I','L','D' 或 'F' 中的任何一个。
  * str = PtrData#to_s([len])
    o 返回长度为len的字符串。若省略len时, 字符串末尾是'\0'。
  * ptr = PtrData#ptr,+@
    o 以 PtrData对象ptr来返回指针所指的值。(译注:?)(译注:把PtrData所指的值看做是指针,然后以PtrData返回(?))
  * ptr = PtrData#ref,-@
    o 以PtrData对象ptr来返回引用。(译注:?)(译注:把PtrData当做指向PtrData的引用,然后返回(?)) (译注:把PtrData当做指向PtrData的指针,然后返回(?))
  * ptr = PtrData#+
    o 返回PtrData 对象。(译注: 增加了参数的字节数后,返回这个新的PtrData对象)
  * ptr = PtrData#-
    o 返回PtrData 对象。(译注: 缩减了参数的字节数后,返回这个新的PtrData对象)
  * PtrData#struct!(type, *members)
    o 定义使用符号访问结构体成员的数据类型(请参考PtrData#[])
  * PtrData#union!(type, *members)
    o 定义使用符号访问共同体成员的数据类型(请参考PtrData#[])
  * val = PtrData#[key], PtrData#[key, num = 0]
    o 若key是字符串或符号, 则该方法返回结构体/共同体成员的值。它包含PtrData#{struct!,union!}中定义的类型。若key是整数且该对象对应于指针ptr的话, 则返回`(ptr + key).to_s(num)'的值.
  * PtrData#[key,num]=val, PtrData#[key]=val
    o 若key是字符串或符号, 则该方法将结构体/共同体成员的值设为val。若key是整数且val是字符串时, 使用memcpy(3)将值中的num 字节拷贝到内存空间ptr中。

Type specifiers

原型是由下列类型分类符构成的。原型的首元素表示返回值的类型, 其余元素表示各参数的类型。

C : 字符 (char)
c : 指向字符的指针 (char *)
H : short 整数 (short)
h : 指向short整数的指针 (short *)
I : 整数 (char, short, int)
i : 指向整数的指针 (char *, short *, int *)
L : long 整数 (long)
l : 指向long整数的指针 (long *)
F : 实数 (float)
f : 指向实数的指针 (float *)
D : 实数 (double)
d : 指向实数的指针(double *)
S : 不可变(immutable)字符串 (const char *)
s : 可变(mutable)字符串 (char *)
A : 数组(const type[])
a : 可变(mutable)数组 (type[])
P : 指针 (void *)
p : 可变(mutable)指针 (void *)
0 : void 函数(必须是原型的首字符)

cbtype由类型分类符0, C, I, H, L, F, D, S 以及 P 构成。例如:

DL.callback('IPP'){|ptr1,ptr2|
 str1 = ptr1.ptr.to_s
 str2 = ptr2.ptr.to_s
 str1 <=> str2
}
DL::Importable
超类

  * Module

方法

dlload(lib,...)

  使用DL::dlopen来加载库, 这样就可以在被extend的模块中使用该库中定义的那些可引用的符号了。
extern(prototype)

  给出C的函数原型之后, 就可以动态地定义调用该函数的方法。若首字符为大写,则自动将其变为小写。
callback(proto)

  若给出C的函数原型之后, 就可以把以定义的Ruby方法作为C的回叫函数来处理。返回DL::Symbol对象。
typealias(newtype, oldtype)

  将newtype类型定义为oldtype类型的别名。在给出extern或callback方法的原型时就会用到newtype中的类型。
symbol(sym[, typespec])

  取出符号名为sym的符号。传给typespec的是类型信息, 返回DL::Symbol对象。若省略typespec时,则以DL::DataPtr对象返回指向符号的引用。

补充

实际上, 上述方法是定义在DL::Importable::Internal中的。因为Importable模块内含Internal模块, 所以就由Importable模块来提供这些方法。
相关文件

  * dl.so
  * dl/types.rb
  * dl/struct.rb
DL::Importable
概要

它提供了在(已添加过DL::Importable的)模块内定义结构体/共用体的功能。
方法

define_struct(contents), struct(contents)

  定义结构体。欲知contents详情,请参考DL::Importable::Struct#initialize。
define_union(contents), union(contents)

  定义共用体。有关contents的详细情况,请参考上面的define_struct。

DL::Importable::Memory
概要

用来封装DL::PtrData的类。使用dot形式就可以访问结构体和共用体中的元素。调用Struct、Union的实例的malloc、new方法时,就会生成Memory类的实例。因此,通常情况下没有必要直接生成。
方法

initialize(ptr, names, ty, len, enc, dec)

  动态定义访问DL::PtrData对象ptr的各成员的方法。Struct,Union的实例会保存这些信息。
to_ptr

  返回所保存的DL::PtrData对象。
size

  调用DL::PtrData#size。

DL::Importable::Struct
方法

initialize(types, contents)

  像下面这样把DL::Types的实例传给types,把结构体的定义传给contents。

  ["int size",
  "char *str"]

  这样生成的Struct对象的运作情况类似于下面的结构体。

  struct {
  int size;
  char *str;
  }

new(ptr)

  返回Memory对象,其中保存着DL::PtrData对象ptr的信息。
malloc(size = nil)

  划出size字节的内存空间,生成DL::PtrData对象,并返回一个保存着该对象的Memory对象。

DL::Importable::Union

与Struct基本相同,但它是面向共用体的类。

补充内容

上述方法和类实际上是定义在DL::Importable::Internal中的。
相关文件

  * dl.so
  * dl/import.rb
  * dl/types.rb
定义类型。内部包含形如

["alias name", "type name",
encoding_method, decoding_method, for function prototypes
encoding_method, decoding_method] for structures (not implemented)

的数组。它定义了别名和实际的类型、编码、解码的方法。DL::Types::TYPES是默认的定义。
DL::Types

保存类型定义的对象的类。

typealias(alias, type, enc, dec, struct_enc, struct_dec)

  添加类型定义。在实例变量@TYDEFS的前面添加如下内容。

  [alias, type,
  enc, dec, struct_end, struct_dec]

encode_type(alias)

  以下面数组的形式返回几种Proc对象,它们分别是:将DL模块中用到的类型定义和Ruby对象编码为DL模块中使用的数据时所使用的Proc对象 和 将DL模块中的数据解码为Ruby对象时所使用的Proc对象。

  [ty,enc,dec,senc,sdec]
  ty : DL中的类型分类符
  enc : 编码用的Proc
  dec : 解码用的Proc
  senc : 编码用的Proc(在dl/struct.rb中使用)
  sdec : 解码用的Proc(在dl/struct.rb中使用)

相关文件

  * dl.so
  * dl/import.rb
  * dl/struct.rb
该库保证了Ruby/DL与Win32API的兼容性。
dRuby --- 为实现分布式对象编程而设置的库

<URL:http://www2a.biglobe.ne.jp/~seki/ruby/druby.html>