From de6d4f7e7bdb78e5cb443a2e327265b52cde0d44 Mon Sep 17 00:00:00 2001 From: drbrain Date: Tue, 16 Aug 2011 00:34:51 +0000 Subject: * 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 --- ext/dl/cfunc.c | 28 ++++++ ext/dl/cptr.c | 9 ++ ext/dl/dl.c | 242 ++++++++++++++++++++++++++++++++++++++++++++++ ext/dl/handle.c | 48 +++++++++ ext/dl/lib/dl/callback.rb | 26 ++++- ext/dl/lib/dl/import.rb | 16 +++ ext/dl/lib/dl/types.rb | 31 +++++- 7 files changed, 393 insertions(+), 7 deletions(-) (limited to 'ext/dl') diff --git a/ext/dl/cfunc.c b/ext/dl/cfunc.c index f076c6f432..66aebf2e79 100644 --- a/ext/dl/cfunc.c +++ b/ext/dl/cfunc.c @@ -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) + * => # + * @cfunc = DL::CFunc.new(libc,['strcpy'], DL::TYPE_VOIDP, '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); diff --git a/ext/dl/cptr.c b/ext/dl/cptr.c index 2f6a65fe52..89dcb942c0 100644 --- a/ext/dl/cptr.c +++ b/ext/dl/cptr.c @@ -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)); } diff --git a/ext/dl/dl.c b/ext/dl/dl.c index 9635794883..e0617047ec 100644 --- a/ext/dl/dl.c +++ b/ext/dl/dl.c @@ -1,3 +1,10 @@ +/* + * ext/dl/dl.c + * + * doumentation: + * - Vincent Batts (vbatts@hashbangbash.com) + * + */ #include #include #include @@ -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 < gcc -o libsum.so -shared sum.c + * bash $> cat > sum.rb < 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(); diff --git a/ext/dl/handle.c b/ext/dl/handle.c index eea8697e06..2037ab5760 100644 --- a/ext/dl/handle.c +++ b/ext/dl/handle.c @@ -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) + * => # + * + * === 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) + * => # + * + * === 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); diff --git a/ext/dl/lib/dl/callback.rb b/ext/dl/lib/dl/callback.rb index 0863c70d4d..1722d3c6b9 100644 --- a/ext/dl/lib/dl/callback.rb +++ b/ext/dl/lib/dl/callback.rb @@ -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) diff --git a/ext/dl/lib/dl/import.rb b/ext/dl/lib/dl/import.rb index f22a53aa84..eec65cdfd6 100644 --- a/ext/dl/lib/dl/import.rb +++ b/ext/dl/lib/dl/import.rb @@ -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 diff --git a/ext/dl/lib/dl/types.rb b/ext/dl/lib/dl/types.rb index b85ac890cd..c79f74f95c 100644 --- a/ext/dl/lib/dl/types.rb +++ b/ext/dl/lib/dl/types.rb @@ -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+ (unsigned int) and + # +ulong+ and +u_long+ (unsigned long) module BasicTypes - def included(m) + def included(m) # :nodoc: m.module_eval{ typealias "uint", "unsigned int" typealias "u_int", "unsigned int" -- cgit v1.2.3