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! :-)

Namespace
Methods
D
F
M
R
S
Constants
NULL = Document-const
 
NULL

A NULL pointer

MAX_CALLBACK = Document-const
 

MAX_CALLBACK

Maximum number of callbacks

DLSTACK_SIZE = Document-const
 

DLSTACK_SIZE

Dynamic linker stack size

RTLD_GLOBAL = 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.

RTLD_LAZY = 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.)

RTLD_NOW = 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.

TYPE_VOID = Document-const: TYPE_VOID DL:
 

CFunc type - void

TYPE_VOIDP = Document-const: TYPE_VOIDP DL:
 

CFunc type - void*

TYPE_CHAR = Document-const: TYPE_CHAR DL:
 

CFunc type - char

TYPE_SHORT = Document-const: TYPE_SHORT DL:
 

CFunc type - short

TYPE_INT = Document-const: TYPE_INT DL:
 

CFunc type - int

TYPE_LONG = Document-const: TYPE_LONG DL:
 

CFunc type - long

TYPE_LONG_LONG = Document-const: TYPE_LONG_LONG DL:
 

CFunc type - long long

TYPE_FLOAT = Document-const: TYPE_FLOAT DL:
 

CFunc type - float

TYPE_DOUBLE = Document-const: TYPE_DOUBLE DL:
 

CFunc type - double

ALIGN_VOIDP = Document-const
 

ALIGN_VOIDP

The Offset of a struct void* and a void*

ALIGN_CHAR = Document-const
 

ALIGN_CHAR

The Offset of a struct char and a char

ALIGN_SHORT = Document-const
 

ALIGN_SHORT

The Offset of a struct short and a short

ALIGN_INT = Document-const
 

ALIGN_INT

The Offset of a struct int and a int

ALIGN_LONG = Document-const
 

ALIGN_LONG

The Offset of a struct long and a long

ALIGN_LONG_LONG = Document-const
 

ALIGN_LONG_LONG

The Offset of a struct long long and a long long

ALIGN_FLOAT = Document-const
 

ALIGN_FLOAT

The Offset of a struct float and a float

ALIGN_DOUBLE = Document-const
 

ALIGN_DOUBLE

The Offset of a struct double and a double

SIZEOF_VOIDP = Document-const
 

SIZEOF_VOIDP

OS Dependent - sizeof(void*)

SIZEOF_CHAR = Document-const
 

SIZEOF_CHAR

OS Dependent - sizeof(char)

SIZEOF_SHORT = Document-const
 

SIZEOF_SHORT

OS Dependent - sizeof(short)

SIZEOF_INT = Document-const
 

SIZEOF_INT

OS Dependent - sizeof(int)

SIZEOF_LONG = Document-const
 

SIZEOF_LONG

OS Dependent - sizeof(long)

SIZEOF_LONG_LONG = Document-const
 

SIZEOF_LONG_LONG

OS Dependent - sizeof(long long)

SIZEOF_FLOAT = Document-const
 

SIZEOF_FLOAT

OS Dependent - sizeof(float)

SIZEOF_DOUBLE = Document-const
 

SIZEOF_DOUBLE

OS Dependent - sizeof(double)

RUBY_FREE = Document-const
 

RUBY_FREE

Address of the ruby_xfree() function

BUILD_RUBY_PLATFORM = Document-const
 

BUILD_RUBY_PLATFORM

Platform built against (i.e. “x86_64-linux”, etc.)

See also RUBY_PLATFORM

BUILD_RUBY_VERSION = Document-const
 

BUILD_RUBY_VERSION

Ruby Version built. (i.e. “1.9.3”)

See also RUBY_VERSION

SEM = Mutex.new # :nodoc:
 

The mutual exclusion (Mutex) semaphore for the DL module

CdeclCallbackProcs = {}
 

A Hash of callback Procs

Uses Fiddle

CdeclCallbackAddrs = {}
 

A Hash of the addresses of callback Proc

Uses Fiddle

StdcallCallbackProcs = {}
 

A Hash of Stdcall callback Procs

Uses Fiddle on win32

StdcallCallbackAddrs = {}
 

A Hash of the addresses of Stdcall callback Procs

Uses Fiddle on win32

Class Public methods
dlopen(*args)
VALUE
rb_dl_dlopen(int argc, VALUE argv[], VALUE self)
{
    return rb_class_new_instance(argc, argv, rb_cDLHandle);
}
dlunwrap(p1)
VALUE
rb_dl_ptr2value(VALUE self, VALUE addr)
{
    rb_secure(4);
    return (VALUE)NUM2PTR(addr);
}
dlwrap(p1)
VALUE
rb_dl_value2ptr(VALUE self, VALUE val)
{
    return PTR2NUM((void*)val);
}
fiddle?()
# File ext/dl/lib/dl.rb, line 9
def self.fiddle?
  Object.const_defined?(:Fiddle)
end
DL.free(addr)

Free the memory at address addr

VALUE
rb_dl_free(VALUE self, VALUE addr)
{
    void *ptr = NUM2PTR(addr);

    rb_secure(4);
    ruby_xfree(ptr);
    return Qnil;
}
DL.malloc

Allocate sizebytes of memory and return the integer memory address for the allocated memory.

VALUE
rb_dl_malloc(VALUE self, VALUE size)
{
    void *ptr;

    rb_secure(4);
    ptr = (void*)ruby_xmalloc(NUM2INT(size));
    return PTR2NUM(ptr);
}
DL.realloc(addr, size)

Change the size of the memory allocated at the memory location addrto sizebytes. Returns the memory address of the reallocated memory, which may be different than the address passed in.

VALUE
rb_dl_realloc(VALUE self, VALUE addr, VALUE size)
{
    void *ptr = NUM2PTR(addr);

    rb_secure(4);
    ptr = (void*)ruby_xrealloc(ptr, NUM2INT(size));
    return PTR2NUM(ptr);
}
Instance Public methods
remove_callback(addr, ctype = nil)
remove_callback_internal(proc_entry, addr_entry, addr, ctype = nil)
# File ext/dl/lib/dl/callback.rb, line 70
def remove_callback_internal(proc_entry, addr_entry, addr, ctype = nil)
  if DL.fiddle?
    addr = addr.to_i
    return false unless proc_entry.key?(addr)
    proc_entry.delete(addr)
    true
  else
    index = nil
    if( ctype )
      addr_entry[ctype].each_with_index{|xaddr, idx|
        if( xaddr == addr )
          index = idx
        end
      }
    else
      addr_entry.each{|ty,entry|
        entry.each_with_index{|xaddr, idx|
          if( xaddr == addr )
            index = idx
          end
        }
      }
    end
    if( index and proc_entry[ctype][index] )
      proc_entry[ctype][index] = nil
      return true
    else
      return false
    end
  end
end
remove_cdecl_callback(addr, ctype = nil)
Also aliased as: remove_callback
# File ext/dl/lib/dl/callback.rb, line 102
def remove_cdecl_callback(addr, ctype = nil)
  remove_callback_internal(CdeclCallbackProcs, CdeclCallbackAddrs, addr, ctype)
end
remove_stdcall_callback(addr, ctype = nil)
# File ext/dl/lib/dl/callback.rb, line 106
def remove_stdcall_callback(addr, ctype = nil)
  remove_callback_internal(StdcallCallbackProcs, StdcallCallbackAddrs, addr, ctype)
end
set_callback(ty, argc, &cbp)
set_callback_internal(proc_entry, addr_entry, argc, ty, abi = nil, &cbp)
# File ext/dl/lib/dl/callback.rb, line 30
def set_callback_internal(proc_entry, addr_entry, argc, ty, abi = nil, &cbp)
  if( argc < 0 )
    raise(ArgumentError, "arity should not be less than 0.")
  end
  addr = nil

  if DL.fiddle?
    abi ||= Fiddle::Function::DEFAULT
    closure = Fiddle::Closure::BlockCaller.new(ty, [TYPE_VOIDP] * argc, abi, &cbp)
    proc_entry[closure.to_i] = closure
    addr = closure.to_i
  else
    SEM.synchronize{
      ary = proc_entry[ty]
      (0...MAX_CALLBACK).each{|n|
        idx = (n * DLSTACK_SIZE) + argc
        if( ary[idx].nil? )
          ary[idx] = cbp
          addr = addr_entry[ty][idx]
          break
        end
      }
    }
  end

  addr
end
set_cdecl_callback(ty, argc, &cbp)
Also aliased as: set_callback
# File ext/dl/lib/dl/callback.rb, line 58
def set_cdecl_callback(ty, argc, &cbp)
  set_callback_internal(CdeclCallbackProcs, CdeclCallbackAddrs, argc, ty, &cbp)
end
set_stdcall_callback(ty, argc, &cbp)
# File ext/dl/lib/dl/callback.rb, line 62
def set_stdcall_callback(ty, argc, &cbp)
  if DL.fiddle?
    set_callback_internal(StdcallCallbackProcs, StdcallCallbackAddrs, argc, ty, Fiddle::Function::STDCALL, &cbp)
  else
    set_callback_internal(StdcallCallbackProcs, StdcallCallbackAddrs, argc, ty, &cbp)
  end
end