Module: Fiddle

Included in:
Importer
Defined in:
fiddle.c,
lib/fiddle.rb,
lib/fiddle/pack.rb,
lib/fiddle/types.rb,
lib/fiddle/value.rb,
lib/fiddle/struct.rb,
lib/fiddle/import.rb,
lib/fiddle/closure.rb,
lib/fiddle/cparser.rb,
lib/fiddle/function.rb,
fiddle.c,
closure.c

Overview

A libffi wrapper for Ruby.

Description

Fiddle is an extension to translate a foreign function interface (FFI) with ruby.

It wraps libffi, a popular C library which provides a portable interface that allows code written in one language to call code written in another language.

Example

Here we will use Fiddle::Function to wrap floor(3) from libm

require 'fiddle'

libm = Fiddle.dlopen('/lib/libm.so.6')

floor = Fiddle::Function.new(
  libm['floor'],
  [Fiddle::TYPE_DOUBLE],
  Fiddle::TYPE_DOUBLE
)

puts floor.call(3.14159) #=> 3.0

Defined Under Namespace

Modules: BasicTypes, CParser, CStructBuilder, Importer, PackInfo, ValueUtil, Win32Types Classes: CStruct, CStructEntity, CUnion, CUnionEntity, Closure, CompositeHandler, DLError, Function, Handle, Packer, Pointer

Constant Summary collapse

RTLD_GLOBAL =

Add constants for backwards compat

Handle::RTLD_GLOBAL
RTLD_LAZY =
Handle::RTLD_LAZY
RTLD_NOW =

:nodoc: :nodoc: :nodoc:

Handle::RTLD_NOW
TYPE_VOID =

C type - void

INT2NUM(TYPE_VOID)
TYPE_VOIDP =

C type - void*

INT2NUM(TYPE_VOIDP)
TYPE_CHAR =

C type - char

INT2NUM(TYPE_CHAR)
TYPE_SHORT =

C type - short

INT2NUM(TYPE_SHORT)
TYPE_INT =

C type - int

INT2NUM(TYPE_INT)
TYPE_LONG =

C type - long

INT2NUM(TYPE_LONG)
TYPE_LONG_LONG =

C type - long long

INT2NUM(TYPE_LONG_LONG)
TYPE_FLOAT =

C type - float

INT2NUM(TYPE_FLOAT)
TYPE_DOUBLE =

C type - double

INT2NUM(TYPE_DOUBLE)
TYPE_SIZE_T =

C type - size_t

INT2NUM(TYPE_SIZE_T)
TYPE_SSIZE_T =

C type - ssize_t

INT2NUM(TYPE_SSIZE_T)
TYPE_PTRDIFF_T =

C type - ptrdiff_t

INT2NUM(TYPE_PTRDIFF_T)
TYPE_INTPTR_T =

C type - intptr_t

INT2NUM(TYPE_INTPTR_T)
TYPE_UINTPTR_T =

C type - uintptr_t

INT2NUM(TYPE_UINTPTR_T)
ALIGN_VOIDP =

The alignment size of a void*

INT2NUM(ALIGN_VOIDP)
ALIGN_CHAR =

The alignment size of a char

INT2NUM(ALIGN_CHAR)
ALIGN_SHORT =

The alignment size of a short

INT2NUM(ALIGN_SHORT)
ALIGN_INT =

The alignment size of an int

INT2NUM(ALIGN_INT)
ALIGN_LONG =

The alignment size of a long

INT2NUM(ALIGN_LONG)
ALIGN_LONG_LONG =

The alignment size of a long long

INT2NUM(ALIGN_LONG_LONG)
ALIGN_FLOAT =

The alignment size of a float

INT2NUM(ALIGN_FLOAT)
ALIGN_DOUBLE =

The alignment size of a double

INT2NUM(ALIGN_DOUBLE)
ALIGN_SIZE_T =

The alignment size of a size_t

INT2NUM(ALIGN_OF(size_t))
ALIGN_SSIZE_T =

same as size_t

INT2NUM(ALIGN_OF(size_t))
ALIGN_PTRDIFF_T =

The alignment size of a ptrdiff_t

INT2NUM(ALIGN_OF(ptrdiff_t))
ALIGN_INTPTR_T =

The alignment size of a intptr_t

INT2NUM(ALIGN_OF(intptr_t))
ALIGN_UINTPTR_T =

The alignment size of a uintptr_t

INT2NUM(ALIGN_OF(uintptr_t))
WINDOWS =
Qfalse
SIZEOF_VOIDP =

size of a void*

INT2NUM(sizeof(void*))
SIZEOF_CHAR =

size of a char

INT2NUM(sizeof(char))
SIZEOF_SHORT =

size of a short

INT2NUM(sizeof(short))
SIZEOF_INT =

size of an int

INT2NUM(sizeof(int))
SIZEOF_LONG =

size of a long

INT2NUM(sizeof(long))
SIZEOF_LONG_LONG =

size of a long long

INT2NUM(sizeof(LONG_LONG))
SIZEOF_FLOAT =

size of a float

INT2NUM(sizeof(float))
SIZEOF_DOUBLE =

size of a double

INT2NUM(sizeof(double))
SIZEOF_SIZE_T =

size of a size_t

INT2NUM(sizeof(size_t))
SIZEOF_SSIZE_T =

same as size_t

INT2NUM(sizeof(size_t))
SIZEOF_PTRDIFF_T =

size of a ptrdiff_t

INT2NUM(sizeof(ptrdiff_t))
SIZEOF_INTPTR_T =

size of a intptr_t

INT2NUM(sizeof(intptr_t))
SIZEOF_UINTPTR_T =

size of a uintptr_t

INT2NUM(sizeof(uintptr_t))
RUBY_FREE =

Address of the ruby_xfree() function

PTR2NUM(ruby_xfree)
BUILD_RUBY_PLATFORM =

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

See also RUBY_PLATFORM

rb_str_new2(RUBY_PLATFORM)
NULL =

A NULL pointer

rb_fiddle_ptr_new(0, 0, 0)

Class Method Summary collapse

Class Method Details

.dlopen(library) ⇒ Object

call-seq: dlopen(library) => Fiddle::Handle

Creates a new handler that opens library, and returns an instance of Fiddle::Handle.

If nil is given for the library, Fiddle::Handle::DEFAULT is used, which is the equivalent to RTLD_DEFAULT. See man 3 dlopen for more.

lib = Fiddle.dlopen(nil)

The default is dependent on OS, and provide a handle for all libraries already loaded. For example, in most cases you can use this to access libc functions, or ruby functions like rb_str_new.

See Fiddle::Handle.new for more.



45
46
47
# File 'lib/fiddle.rb', line 45

def dlopen library
  Fiddle::Handle.new library
end

.dlunwrap(addr) ⇒ Object

Returns the hexadecimal representation of a memory pointer address addr

Example:

lib = Fiddle.dlopen('/lib64/libc-2.15.so')
=> #<Fiddle::Handle:0x00000001342460>

lib['strcpy'].to_s(16)
=> "7f59de6dd240"

Fiddle.dlunwrap(Fiddle.dlwrap(lib['strcpy'].to_s(16)))
=> "7f59de6dd240"


101
102
103
104
105
# File 'fiddle.c', line 101

VALUE
rb_fiddle_ptr2value(VALUE self, VALUE addr)
{
    return (VALUE)NUM2PTR(addr);
}

.dlwrap(val) ⇒ Object

Returns a memory pointer of a function's hexadecimal address location val

Example:

lib = Fiddle.dlopen('/lib64/libc-2.15.so')
=> #<Fiddle::Handle:0x00000001342460>

Fiddle.dlwrap(lib['strcpy'].to_s(16))
=> 25522520


120
121
122
123
124
# File 'fiddle.c', line 120

static VALUE
rb_fiddle_value2ptr(VALUE self, VALUE val)
{
    return PTR2NUM((void*)val);
}

.free(addr) ⇒ Object

Free the memory at address addr



76
77
78
79
80
81
82
83
# File 'fiddle.c', line 76

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

    ruby_xfree(ptr);
    return Qnil;
}

.last_errorObject

Returns the last Error of the current executing Thread or nil if none



20
21
22
# File 'lib/fiddle.rb', line 20

def self.last_error
  Thread.current[:__FIDDLE_LAST_ERROR__]
end

.last_error=(error) ⇒ Object

Sets the last Error of the current executing Thread to error



25
26
27
28
# File 'lib/fiddle.rb', line 25

def self.last_error= error
  Thread.current[:__DL2_LAST_ERROR__] = error
  Thread.current[:__FIDDLE_LAST_ERROR__] = error
end

.malloc(size) ⇒ Object

Allocate size bytes of memory and return the integer memory address for the allocated memory.



46
47
48
49
50
51
52
53
# File 'fiddle.c', line 46

static VALUE
rb_fiddle_malloc(VALUE self, VALUE size)
{
    void *ptr;

    ptr = (void*)ruby_xmalloc(NUM2INT(size));
    return PTR2NUM(ptr);
}

.realloc(addr, size) ⇒ Object

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



62
63
64
65
66
67
68
69
# File 'fiddle.c', line 62

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

    ptr = (void*)ruby_xrealloc(ptr, NUM2INT(size));
    return PTR2NUM(ptr);
}

.win32_last_errorObject

Returns the last win32 Error of the current executing Thread or nil if none



9
10
11
# File 'lib/fiddle.rb', line 9

def self.win32_last_error
  Thread.current[:__FIDDLE_WIN32_LAST_ERROR__]
end

.win32_last_error=(error) ⇒ Object

Sets the last win32 Error of the current executing Thread to error



14
15
16
# File 'lib/fiddle.rb', line 14

def self.win32_last_error= error
  Thread.current[:__FIDDLE_WIN32_LAST_ERROR__] = error
end