summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/dl/cfunc.c28
-rw-r--r--ext/dl/cptr.c9
-rw-r--r--ext/dl/dl.c242
-rw-r--r--ext/dl/handle.c48
-rw-r--r--ext/dl/lib/dl/callback.rb26
-rw-r--r--ext/dl/lib/dl/import.rb16
-rw-r--r--ext/dl/lib/dl/types.rb31
7 files changed, 393 insertions, 7 deletions
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)
+ * => #<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);
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 <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();
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)
+ * => #<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);
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+ (<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"