Ruby/DL an interface to dynamic linking loader ------------------------------------------------------------------------------- Ruby/DL `Ruby/DL' provides an interface to the dynamic linking loader. ------------------------------------------------------------------------------- Installing $ ruby extconf.rb # to create the Makefile $ make # to build the library 'dl.so' $ make libtest.so # to build the C library 'libtest.so' for the test script $ make test # to run the test script $ make install # to install the library $ make clean # to remove the created files without Makefile $ make distclean # to remove the all created files ------------------------------------------------------------------------------- Functions and Classes after loading the `dl' library, we get access to the module called `DL'. the DL module has the following constants, functions and classes. Constants VERSION MAJOR_VERSION MINOR_VERSION PATCH_VERSION RTLD_GLOBAL RTLD_LAZY RTLD_NOW MAX_ARG MAX_CBARG MAX_CBENT Functions handle = dlopen(lib){|handle| ... } is quite equal to `Handle.new(lib)' sym = set_callback(cbtype, entry){|args| ... } sym = set_callback(cbtype, entry, proc) makes entry-th pre-defined function to call the proc or given block. the entry-th pre-defined function is specified by cbtype and entry. cbtype is a prototype of the callback. see also the section `Type specifiers' about cbtype. sym = get_callback(cbtype, entry) returns the Proc object which is given by the above function `set_callback'. ptr = malloc(size, [free = nil]) allocates the size bytes, and returns the pointer as a PtrData object ptr. ptr = strdup(str) returns a PtrData object ptr which represents the pointer to a new string which is a duplicate of the string str. size = sizeof(type) returns the size of type. `sizeof("C") + sizeof("L")' is not equal to `sizeof("CL")'. the latter is assumed to returns the enough size of the structure `struct foo { char c; long l; }', but the size may not equal to `sizeof(foo)' of C. class Handle handle = Handle.new(lib){|handle| ... } opens a library lib and returns a Handle object handle. if a block is given, the handle is automatically closed as the block ends. Handle#close closes the handle opened by the above Handle.new(lib). sym = Handle#sym(func, prototype = "0") sym = Handle#[func, prototype = nil] obtains the pointer to a function called func and returns a Symbol object or a DataPtr object. prototype is a string which consists of type specifiers, it indicates the function's prototype. see also the section `Type specifiers'. class Symbol sym = Symbol.new(addr, type = nil, name = nil) creates the Symbol object sym with the type type if type is not nil. addr is the address where the function is allocated. If type is nil, it returns a DataPtr object. Symbol::char2type(char) takes a character char that represents a type and returns the type specifier of the C language. str = Symbol#proto() returns the function prototype. str = Symbol#name() Returns the function name. str = Symbol#cproto() str = Symbol#to_s() returns the prototype of the C language. str = Symbol#inspect() returns the inspectable string. r,rs = Symbol#call(arg1,arg2,...,argN) r,rs = Symbol#[](arg1,arg2,...,argN) calls the function with parameters arg1, arg2, ..., argN. and the result consists of the return value r and parameters rs. rs is an array. ptr = Symbol#to_ptr returns the corresponding PtrData object ptr. class PtrData ptr = PtrData.new(addr, [free = nil]) returns the PtrData object representing the pointer which indicates the address addr. GC frees the memory using the free function. PtrData#free=(sym) if you specify a symbol object sym, GC frees the memory using the function represented by sym. sym = PtrData#free returns a symbol object sym which is used when GC frees the memory. it usually configured by `PtrData#free=' or `PtrData.new'. size = PtrData#size, PtrData#size=(size) gets and sets allocated size of the memory. ary = PtrData#to_a(type, [size]) returns an array of the type which specified with type. type must be one of 'S','P','I','L','D' and 'F'. str = PtrData#to_s([len]) returns a string which length is len. if len is omitted, the end of the string is '\0'. ptr = PtrData#ptr,+@ returns the pointed value as a PtrData object ptr. ptr = PtrData#ref,-@ returns the reference as a PtrData object ptr. ptr = PtrData#+ returns the PtrData object ptr = PtrData#- returns the PtrData object PtrData#struct!(type, *members) defines the data type to get access to a structure member with a symbol. (see also PtrData#[]) PtrData#union!(type, *members) defines the data type to get access to a union member with a symbol. (see also PtrData#[]) val = PtrData#[key], PtrData#[key, num = 0] if the key is a string or symbol, this method returns the value of the structure/union member which has the type defined by PtrData# {struct!,union!}. if the key is a integer value and this object represents the pointer ptr, it returns the value of `(ptr + key).to_s(num)' PtrData#[key,num]=val, PtrData#[key]=val if the key is a string or symbol, this method substitute the value of the structure/union member with val. if the key is a integer value and val is a string, this method copies num bytes of val to the memory area ptr using memcpy(3). ------------------------------------------------------------------------------- Type specifiers the prototype consists of the following type specifiers, first element of prototype represents the type of return value, and remaining elements represent the type of each argument. C : a character (char) c : a pointer to a character (char *) H : a short integer (short) h : a pointer to a short integer (short *) I : an integer (char, short, int) i : a pointer to an integer (char *, short *, int *) L : a long integer (long) l : a pointer to a long integer (long *) F : a real (float) f : a pointer to a real (float *) D : a real (double) d : a pointer to a real (double *) S : an immutable string (const char *) s : a mutable string (char *) A : an array (const type[]) a : a mutable array (type[]) P : a pointer (void *) p : a mutable object (void *) 0 : void function (this must be a first character of the prototype) the cbtype consists of type specifiers 0, I, L, D and P. for example: DL.set_callback('IPP',0){|ptr1,ptr2| str1 = ptr1.ptr.to_s str2 = ptr2.ptr.to_s return str1 <=> str2 } ------------------------------------------------------------------------------- ttate@kt.jaist.ac.jp