зеркало из https://github.com/github/ruby.git
* ext/dl: Add documentation. Patch by Vincent Batts. [Ruby 1.9 - Bug #5192]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32982 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
87ff4b24ae
Коммит
de6d4f7e7b
|
@ -1,3 +1,8 @@
|
|||
Tue Aug 16 09:31:44 2011 Eric Hodel <drbrain@segment7.net>
|
||||
|
||||
* ext/dl: Add documentation. Patch by Vincent Batts.
|
||||
[Ruby 1.9 - Bug #5192]
|
||||
|
||||
Tue Aug 16 08:48:26 2011 Eric Hodel <drbrain@segment7.net>
|
||||
|
||||
* ext/.document (fiddle): Remove duplicate entry
|
||||
|
|
|
@ -620,10 +620,38 @@ Init_dlcfunc(void)
|
|||
#if defined(_WIN32)
|
||||
id_win32_last_error = rb_intern("__DL2_WIN32_LAST_ERROR__");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Document-class: DL::CFunc
|
||||
*
|
||||
* A direct accessor to a function in a C library
|
||||
*
|
||||
* == Example
|
||||
*
|
||||
* libc_so = "/lib64/libc.so.6"
|
||||
* => "/lib64/libc.so.6"
|
||||
* libc = DL::dlopen(libc_so)
|
||||
* => #<DL::Handle:0x00000000e05b00>
|
||||
* @cfunc = DL::CFunc.new(libc,['strcpy'], DL::TYPE_VOIDP, 'strcpy')
|
||||
* => #<DL::CFunc:0x000000012daec0 ptr=0x007f62ca5a8300 type=1 name='strcpy'>
|
||||
*
|
||||
*/
|
||||
rb_cDLCFunc = rb_define_class_under(rb_mDL, "CFunc", rb_cObject);
|
||||
rb_define_alloc_func(rb_cDLCFunc, rb_dlcfunc_s_allocate);
|
||||
|
||||
/*
|
||||
* Document-method: last_error
|
||||
*
|
||||
* Returns the last error for the current executing thread
|
||||
*/
|
||||
rb_define_module_function(rb_cDLCFunc, "last_error", rb_dl_get_last_error, 0);
|
||||
#if defined(_WIN32)
|
||||
|
||||
/*
|
||||
* Document-method: win32_last_error
|
||||
*
|
||||
* Returns the last win32 error for the current executing thread
|
||||
*/
|
||||
rb_define_module_function(rb_cDLCFunc, "win32_last_error", rb_dl_get_win32_last_error, 0);
|
||||
#endif
|
||||
rb_define_method(rb_cDLCFunc, "initialize", rb_dlcfunc_initialize, -1);
|
||||
|
|
|
@ -640,6 +640,11 @@ Init_dlptr(void)
|
|||
{
|
||||
id_to_ptr = rb_intern("to_ptr");
|
||||
|
||||
/* Document-class: DL::CPtr
|
||||
*
|
||||
* CPtr is a class to handle C pointers
|
||||
*
|
||||
*/
|
||||
rb_cDLCPtr = rb_define_class_under(rb_mDL, "CPtr", rb_cObject);
|
||||
rb_define_alloc_func(rb_cDLCPtr, rb_dlptr_s_allocate);
|
||||
rb_define_singleton_method(rb_cDLCPtr, "malloc", rb_dlptr_s_malloc, -1);
|
||||
|
@ -669,5 +674,9 @@ Init_dlptr(void)
|
|||
rb_define_method(rb_cDLCPtr, "size", rb_dlptr_size_get, 0);
|
||||
rb_define_method(rb_cDLCPtr, "size=", rb_dlptr_size_set, 1);
|
||||
|
||||
/* Document-const: NULL
|
||||
*
|
||||
* A NULL pointer
|
||||
*/
|
||||
rb_define_const(rb_mDL, "NULL", rb_dlptr_new(0, 0, 0));
|
||||
}
|
||||
|
|
242
ext/dl/dl.c
242
ext/dl/dl.c
|
@ -1,3 +1,10 @@
|
|||
/*
|
||||
* ext/dl/dl.c
|
||||
*
|
||||
* doumentation:
|
||||
* - Vincent Batts (vbatts@hashbangbash.com)
|
||||
*
|
||||
*/
|
||||
#include <ruby/ruby.h>
|
||||
#include <ruby/io.h>
|
||||
#include <ctype.h>
|
||||
|
@ -100,51 +107,268 @@ Init_dl(void)
|
|||
rbdl_id_cdecl = rb_intern_const("cdecl");
|
||||
rbdl_id_stdcall = rb_intern_const("stdcall");
|
||||
|
||||
/* Document-module: DL
|
||||
*
|
||||
* A bridge to the dlopen() or dynamic library linker function.
|
||||
*
|
||||
* == Example
|
||||
*
|
||||
* bash $> cat > sum.c <<EOF
|
||||
* double sum(double *arry, int len)
|
||||
* {
|
||||
* double ret = 0;
|
||||
* int i;
|
||||
* for(i = 0; i < len; i++){
|
||||
* ret = ret + arry[i];
|
||||
* }
|
||||
* return ret;
|
||||
* }
|
||||
*
|
||||
* double split(double num)
|
||||
* {
|
||||
* double ret = 0;
|
||||
* ret = num / 2;
|
||||
* return ret;
|
||||
* }
|
||||
* EOF
|
||||
* bash $> gcc -o libsum.so -shared sum.c
|
||||
* bash $> cat > sum.rb <<EOF
|
||||
* require 'dl'
|
||||
* require 'dl/import'
|
||||
*
|
||||
* module LibSum
|
||||
* extend DL::Importer
|
||||
* dlload './libsum.so'
|
||||
* extern 'double sum(double*, int)'
|
||||
* extern 'double split(double)'
|
||||
* end
|
||||
*
|
||||
* a = [2.0, 3.0, 4.0]
|
||||
*
|
||||
* sum = LibSum.sum(a.pack("d*"), a.count)
|
||||
* p LibSum.split(sum)
|
||||
* EOF
|
||||
* bash $> ruby sum.rb
|
||||
* 4.5
|
||||
*
|
||||
* WIN! :-)
|
||||
*/
|
||||
rb_mDL = rb_define_module("DL");
|
||||
|
||||
/*
|
||||
* Document-class: DL::DLError
|
||||
*
|
||||
* standard dynamic load exception
|
||||
*/
|
||||
rb_eDLError = rb_define_class_under(rb_mDL, "DLError", rb_eStandardError);
|
||||
|
||||
/*
|
||||
* Document-class: DL::DLTypeError
|
||||
*
|
||||
* dynamic load incorrect type exception
|
||||
*/
|
||||
rb_eDLTypeError = rb_define_class_under(rb_mDL, "DLTypeError", rb_eDLError);
|
||||
|
||||
/* Document-const: MAX_CALLBACK
|
||||
*
|
||||
* Maximum number of callbacks
|
||||
*/
|
||||
rb_define_const(rb_mDL, "MAX_CALLBACK", INT2NUM(MAX_CALLBACK));
|
||||
|
||||
/* Document-const: DLSTACK_SIZE
|
||||
*
|
||||
* Dynamic linker stack size
|
||||
*/
|
||||
rb_define_const(rb_mDL, "DLSTACK_SIZE", INT2NUM(DLSTACK_SIZE));
|
||||
|
||||
rb_dl_init_callbacks(rb_mDL);
|
||||
|
||||
/* Document-const: RTLD_GLOBAL
|
||||
*
|
||||
* rtld DL::Handle flag.
|
||||
*
|
||||
* The symbols defined by this library will be made available for symbol
|
||||
* resolution of subsequently loaded libraries.
|
||||
*/
|
||||
rb_define_const(rb_mDL, "RTLD_GLOBAL", INT2NUM(RTLD_GLOBAL));
|
||||
|
||||
/* Document-const: RTLD_LAZY
|
||||
*
|
||||
* rtld DL::Handle flag.
|
||||
*
|
||||
* Perform lazy binding. Only resolve symbols as the code that references
|
||||
* them is executed. If the symbol is never referenced, then it is never
|
||||
* resolved. (Lazy binding is only performed for function references;
|
||||
* references to variables are always immediately bound when the library
|
||||
* is loaded.)
|
||||
*/
|
||||
rb_define_const(rb_mDL, "RTLD_LAZY", INT2NUM(RTLD_LAZY));
|
||||
|
||||
/* Document-const: RTLD_NOW
|
||||
*
|
||||
* rtld DL::Handle flag.
|
||||
*
|
||||
* If this value is specified or the environment variable LD_BIND_NOW is
|
||||
* set to a nonempty string, all undefined symbols in the library are
|
||||
* resolved before dlopen() returns. If this cannot be done an error is
|
||||
* returned.
|
||||
*/
|
||||
rb_define_const(rb_mDL, "RTLD_NOW", INT2NUM(RTLD_NOW));
|
||||
|
||||
/* Document-const: TYPE_VOID
|
||||
*
|
||||
* DL::CFunc type - void
|
||||
*/
|
||||
rb_define_const(rb_mDL, "TYPE_VOID", INT2NUM(DLTYPE_VOID));
|
||||
|
||||
/* Document-const: TYPE_VOIDP
|
||||
*
|
||||
* DL::CFunc type - void*
|
||||
*/
|
||||
rb_define_const(rb_mDL, "TYPE_VOIDP", INT2NUM(DLTYPE_VOIDP));
|
||||
|
||||
/* Document-const: TYPE_CHAR
|
||||
*
|
||||
* DL::CFunc type - char
|
||||
*/
|
||||
rb_define_const(rb_mDL, "TYPE_CHAR", INT2NUM(DLTYPE_CHAR));
|
||||
|
||||
/* Document-const: TYPE_SHORT
|
||||
*
|
||||
* DL::CFunc type - short
|
||||
*/
|
||||
rb_define_const(rb_mDL, "TYPE_SHORT", INT2NUM(DLTYPE_SHORT));
|
||||
|
||||
/* Document-const: TYPE_INT
|
||||
*
|
||||
* DL::CFunc type - int
|
||||
*/
|
||||
rb_define_const(rb_mDL, "TYPE_INT", INT2NUM(DLTYPE_INT));
|
||||
|
||||
/* Document-const: TYPE_LONG
|
||||
*
|
||||
* DL::CFunc type - long
|
||||
*/
|
||||
rb_define_const(rb_mDL, "TYPE_LONG", INT2NUM(DLTYPE_LONG));
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
/* Document-const: TYPE_LONG_LONG
|
||||
*
|
||||
* DL::CFunc type - long long
|
||||
*/
|
||||
rb_define_const(rb_mDL, "TYPE_LONG_LONG", INT2NUM(DLTYPE_LONG_LONG));
|
||||
#endif
|
||||
|
||||
/* Document-const: TYPE_FLOAT
|
||||
*
|
||||
* DL::CFunc type - float
|
||||
*/
|
||||
rb_define_const(rb_mDL, "TYPE_FLOAT", INT2NUM(DLTYPE_FLOAT));
|
||||
|
||||
/* Document-const: TYPE_DOUBLE
|
||||
*
|
||||
* DL::CFunc type - double
|
||||
*/
|
||||
rb_define_const(rb_mDL, "TYPE_DOUBLE", INT2NUM(DLTYPE_DOUBLE));
|
||||
|
||||
/* Document-const: ALIGN_VOIDP
|
||||
*
|
||||
* The Offset of a struct void* and a void*
|
||||
*/
|
||||
rb_define_const(rb_mDL, "ALIGN_VOIDP", INT2NUM(ALIGN_VOIDP));
|
||||
|
||||
/* Document-const: ALIGN_CHAR
|
||||
*
|
||||
* The Offset of a struct char and a char
|
||||
*/
|
||||
rb_define_const(rb_mDL, "ALIGN_CHAR", INT2NUM(ALIGN_CHAR));
|
||||
|
||||
/* Document-const: ALIGN_SHORT
|
||||
*
|
||||
* The Offset of a struct short and a short
|
||||
*/
|
||||
rb_define_const(rb_mDL, "ALIGN_SHORT", INT2NUM(ALIGN_SHORT));
|
||||
|
||||
/* Document-const: ALIGN_INT
|
||||
*
|
||||
* The Offset of a struct int and a int
|
||||
*/
|
||||
rb_define_const(rb_mDL, "ALIGN_INT", INT2NUM(ALIGN_INT));
|
||||
|
||||
/* Document-const: ALIGN_LONG
|
||||
*
|
||||
* The Offset of a struct long and a long
|
||||
*/
|
||||
rb_define_const(rb_mDL, "ALIGN_LONG", INT2NUM(ALIGN_LONG));
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
/* Document-const: ALIGN_LONG_LONG
|
||||
*
|
||||
* The Offset of a struct long long and a long long
|
||||
*/
|
||||
rb_define_const(rb_mDL, "ALIGN_LONG_LONG", INT2NUM(ALIGN_LONG_LONG));
|
||||
#endif
|
||||
|
||||
/* Document-const: ALIGN_FLOAT
|
||||
*
|
||||
* The Offset of a struct float and a float
|
||||
*/
|
||||
rb_define_const(rb_mDL, "ALIGN_FLOAT", INT2NUM(ALIGN_FLOAT));
|
||||
|
||||
/* Document-const: ALIGN_DOUBLE
|
||||
*
|
||||
* The Offset of a struct double and a double
|
||||
*/
|
||||
rb_define_const(rb_mDL, "ALIGN_DOUBLE",INT2NUM(ALIGN_DOUBLE));
|
||||
|
||||
/* Document-const: SIZEOF_VOIDP
|
||||
*
|
||||
* OS Dependent - sizeof(void*)
|
||||
*/
|
||||
rb_define_const(rb_mDL, "SIZEOF_VOIDP", INT2NUM(sizeof(void*)));
|
||||
|
||||
/* Document-const: SIZEOF_CHAR
|
||||
*
|
||||
* OS Dependent - sizeof(char)
|
||||
*/
|
||||
rb_define_const(rb_mDL, "SIZEOF_CHAR", INT2NUM(sizeof(char)));
|
||||
|
||||
/* Document-const: SIZEOF_SHORT
|
||||
*
|
||||
* OS Dependent - sizeof(short)
|
||||
*/
|
||||
rb_define_const(rb_mDL, "SIZEOF_SHORT", INT2NUM(sizeof(short)));
|
||||
|
||||
/* Document-const: SIZEOF_INT
|
||||
*
|
||||
* OS Dependent - sizeof(int)
|
||||
*/
|
||||
rb_define_const(rb_mDL, "SIZEOF_INT", INT2NUM(sizeof(int)));
|
||||
|
||||
/* Document-const: SIZEOF_LONG
|
||||
*
|
||||
* OS Dependent - sizeof(long)
|
||||
*/
|
||||
rb_define_const(rb_mDL, "SIZEOF_LONG", INT2NUM(sizeof(long)));
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
/* Document-const: SIZEOF_LONG_LONG
|
||||
*
|
||||
* OS Dependent - sizeof(long long)
|
||||
*/
|
||||
rb_define_const(rb_mDL, "SIZEOF_LONG_LONG", INT2NUM(sizeof(LONG_LONG)));
|
||||
#endif
|
||||
|
||||
/* Document-const: SIZEOF_FLOAT
|
||||
*
|
||||
* OS Dependent - sizeof(float)
|
||||
*/
|
||||
rb_define_const(rb_mDL, "SIZEOF_FLOAT", INT2NUM(sizeof(float)));
|
||||
|
||||
/* Document-const: SIZEOF_DOUBLE
|
||||
*
|
||||
* OS Dependent - sizeof(double)
|
||||
*/
|
||||
rb_define_const(rb_mDL, "SIZEOF_DOUBLE",INT2NUM(sizeof(double)));
|
||||
|
||||
rb_define_module_function(rb_mDL, "dlwrap", rb_dl_value2ptr, 1);
|
||||
|
@ -155,8 +379,26 @@ Init_dl(void)
|
|||
rb_define_module_function(rb_mDL, "realloc", rb_dl_realloc, 2);
|
||||
rb_define_module_function(rb_mDL, "free", rb_dl_free, 1);
|
||||
|
||||
/* Document-const: RUBY_FREE
|
||||
*
|
||||
* Address of the ruby_xfree() function
|
||||
*/
|
||||
rb_define_const(rb_mDL, "RUBY_FREE", PTR2NUM(ruby_xfree));
|
||||
|
||||
/* Document-const: BUILD_RUBY_PLATFORM
|
||||
*
|
||||
* Platform built against (i.e. "x86_64-linux", etc.)
|
||||
*
|
||||
* See also RUBY_PLATFORM
|
||||
*/
|
||||
rb_define_const(rb_mDL, "BUILD_RUBY_PLATFORM", rb_str_new2(RUBY_PLATFORM));
|
||||
|
||||
/* Document-const: BUILD_RUBY_VERSION
|
||||
*
|
||||
* Ruby Version built. (i.e. "1.9.3")
|
||||
*
|
||||
* See also RUBY_VERSION
|
||||
*/
|
||||
rb_define_const(rb_mDL, "BUILD_RUBY_VERSION", rb_str_new2(RUBY_VERSION));
|
||||
|
||||
Init_dlhandle();
|
||||
|
|
|
@ -361,11 +361,59 @@ dlhandle_sym(void *handle, const char *name)
|
|||
void
|
||||
Init_dlhandle(void)
|
||||
{
|
||||
/*
|
||||
* Document-class: DL::Handle
|
||||
*
|
||||
* The DL::Handle is the manner to access the dynamic library
|
||||
*
|
||||
* == Example
|
||||
*
|
||||
* === Setup
|
||||
*
|
||||
* libc_so = "/lib64/libc.so.6"
|
||||
* => "/lib64/libc.so.6"
|
||||
* @handle = DL::Handle.new(libc_so)
|
||||
* => #<DL::Handle:0x00000000d69ef8>
|
||||
*
|
||||
* === Setup, with flags
|
||||
*
|
||||
* libc_so = "/lib64/libc.so.6"
|
||||
* => "/lib64/libc.so.6"
|
||||
* @handle = DL::Handle.new(libc_so, DL::RTLD_LAZY | DL::RTLD_GLOBAL)
|
||||
* => #<DL::Handle:0x00000000d69ef8>
|
||||
*
|
||||
* === Addresses to symbols
|
||||
*
|
||||
* strcpy_addr = @handle['strcpy']
|
||||
* => 140062278451968
|
||||
*
|
||||
* or
|
||||
*
|
||||
* strcpy_addr = @handle.sym('strcpy')
|
||||
* => 140062278451968
|
||||
*
|
||||
*/
|
||||
rb_cDLHandle = rb_define_class_under(rb_mDL, "Handle", rb_cObject);
|
||||
rb_define_alloc_func(rb_cDLHandle, rb_dlhandle_s_allocate);
|
||||
rb_define_singleton_method(rb_cDLHandle, "sym", rb_dlhandle_s_sym, 1);
|
||||
rb_define_singleton_method(rb_cDLHandle, "[]", rb_dlhandle_s_sym, 1);
|
||||
|
||||
/* Document-const: NEXT
|
||||
*
|
||||
* A predefined pseudo-handle of RTLD_NEXT
|
||||
*
|
||||
* Which will find the next occurrence of a function in the search order
|
||||
* after the current library.
|
||||
*/
|
||||
rb_define_const(rb_cDLHandle, "NEXT", predefined_dlhandle(RTLD_NEXT));
|
||||
|
||||
/* Document-const: DEFAULT
|
||||
*
|
||||
* A predefined pseudo-handle of RTLD_DEFAULT
|
||||
*
|
||||
* Which will find the first occurrence of the desired symbol using the
|
||||
* default library search order
|
||||
*/
|
||||
rb_define_const(rb_cDLHandle, "DEFAULT", predefined_dlhandle(RTLD_DEFAULT));
|
||||
rb_define_method(rb_cDLHandle, "initialize", rb_dlhandle_initialize, -1);
|
||||
rb_define_method(rb_cDLHandle, "to_i", rb_dlhandle_to_i, 0);
|
||||
|
|
|
@ -2,13 +2,29 @@ require 'dl'
|
|||
require 'thread'
|
||||
|
||||
module DL
|
||||
SEM = Mutex.new
|
||||
# The mutual exclusion (Mutex) semaphore for the DL module
|
||||
SEM = Mutex.new # :nodoc:
|
||||
|
||||
if DL.fiddle?
|
||||
CdeclCallbackProcs = {}
|
||||
CdeclCallbackAddrs = {}
|
||||
StdcallCallbackProcs = {}
|
||||
StdcallCallbackAddrs = {}
|
||||
# A Hash of callback Procs
|
||||
#
|
||||
# Uses Fiddle
|
||||
CdeclCallbackProcs = {} # :nodoc:
|
||||
|
||||
# A Hash of the addresses of callback Proc
|
||||
#
|
||||
# Uses Fiddle
|
||||
CdeclCallbackAddrs = {} # :nodoc:
|
||||
|
||||
# A Hash of Stdcall callback Procs
|
||||
#
|
||||
# Uses Fiddle on win32
|
||||
StdcallCallbackProcs = {} # :nodoc:
|
||||
|
||||
# A Hash of the addresses of Stdcall callback Procs
|
||||
#
|
||||
# Uses Fiddle on win32
|
||||
StdcallCallbackAddrs = {} # :nodoc:
|
||||
end
|
||||
|
||||
def set_callback_internal(proc_entry, addr_entry, argc, ty, abi = nil, &cbp)
|
||||
|
|
|
@ -31,6 +31,22 @@ module DL
|
|||
end
|
||||
end
|
||||
|
||||
# DL::Importer includes the means to dynamically load libraries and build
|
||||
# modules around them including calling extern functions within the C
|
||||
# library that has been loaded.
|
||||
#
|
||||
# == Example
|
||||
#
|
||||
# require 'dl'
|
||||
# require 'dl/import'
|
||||
#
|
||||
# module LibSum
|
||||
# extend DL::Importer
|
||||
# dlload './libsum.so'
|
||||
# extern 'double sum(double*, int)'
|
||||
# extern 'double split(double)'
|
||||
# end
|
||||
#
|
||||
module Importer
|
||||
include DL
|
||||
include CParser
|
||||
|
|
|
@ -1,6 +1,29 @@
|
|||
module DL
|
||||
# Adds Windows type aliases to the including class for use with
|
||||
# DL::Importer.
|
||||
#
|
||||
# The aliases added are:
|
||||
# * ATOM
|
||||
# * BOOL
|
||||
# * BYTE
|
||||
# * DWORD
|
||||
# * HANDLE
|
||||
# * HDC
|
||||
# * HINSTANCE
|
||||
# * HWND
|
||||
# * LPCSTR
|
||||
# * LPSTR
|
||||
# * PBYTE
|
||||
# * PDWORD
|
||||
# * PHANDLE
|
||||
# * PVOID
|
||||
# * PWORD
|
||||
# * UCHAR
|
||||
# * UINT
|
||||
# * ULONG
|
||||
# * WORD
|
||||
module Win32Types
|
||||
def included(m)
|
||||
def included(m) # :nodoc:
|
||||
m.module_eval{
|
||||
typealias "DWORD", "unsigned long"
|
||||
typealias "PDWORD", "unsigned long *"
|
||||
|
@ -26,8 +49,12 @@ module DL
|
|||
module_function :included
|
||||
end
|
||||
|
||||
# Adds basic type aliases to the including class for use with DL::Importer.
|
||||
#
|
||||
# The aliases added are +uint+ and +u_int+ (<tt>unsigned int</tt>) and
|
||||
# +ulong+ and +u_long+ (<tt>unsigned long</tt>)
|
||||
module BasicTypes
|
||||
def included(m)
|
||||
def included(m) # :nodoc:
|
||||
m.module_eval{
|
||||
typealias "uint", "unsigned int"
|
||||
typealias "u_int", "unsigned int"
|
||||
|
|
Загрузка…
Ссылка в новой задаче