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/import.rb,
lib/fiddle/struct.rb,
lib/fiddle/closure.rb,
lib/fiddle/cparser.rb,
lib/fiddle/version.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, ClearedReferenceError, Closure, CompositeHandler, DLError, Error, Function, Handle, MemoryView, Packer, Pinned, Pointer, StructArray

Constant Summary collapse

RTLD_GLOBAL =

Add constants for backwards compat

Handle::RTLD_GLOBAL
RTLD_LAZY =

:nodoc:

Handle::RTLD_LAZY
RTLD_NOW =

:nodoc:

Handle::RTLD_NOW
VERSION =
"1.0.6"
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_INT8_T =

C type - int8_t

INT2NUM(TYPE_INT8_T)
TYPE_INT16_T =

C type - int16_t

INT2NUM(TYPE_INT16_T)
TYPE_INT32_T =

C type - int32_t

INT2NUM(TYPE_INT32_T)
TYPE_INT64_T =

C type - int64_t

INT2NUM(TYPE_INT64_T)
TYPE_FLOAT =

C type - float

INT2NUM(TYPE_FLOAT)
TYPE_DOUBLE =

C type - double

INT2NUM(TYPE_DOUBLE)
TYPE_VARIADIC =

C type - …

INT2NUM(TYPE_VARIADIC)
TYPE_CONST_STRING =

C type - const char* (‘0’ terminated const char*)

INT2NUM(TYPE_CONST_STRING)
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_INT8_T =

The alignment size of a int8_t

INT2NUM(ALIGN_INT8_T)
ALIGN_INT16_T =

The alignment size of a int16_t

INT2NUM(ALIGN_INT16_T)
ALIGN_INT32_T =

The alignment size of a int32_t

INT2NUM(ALIGN_INT32_T)
ALIGN_INT64_T =

The alignment size of a int64_t

INT2NUM(ALIGN_INT64_T)
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_INT8_T =

size of a int8_t

INT2NUM(sizeof(int8_t))
SIZEOF_INT16_T =

size of a int16_t

INT2NUM(sizeof(int16_t))
SIZEOF_INT32_T =

size of a int32_t

INT2NUM(sizeof(int32_t))
SIZEOF_INT64_T =

size of a int64_t

INT2NUM(sizeof(int64_t))
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))
SIZEOF_CONST_STRING =

size of a const char*

INT2NUM(sizeof(const char*))
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.



48
49
50
# File 'lib/fiddle.rb', line 48

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"


74
75
76
77
78
# File 'fiddle.c', line 74

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


93
94
95
96
97
# File 'fiddle.c', line 93

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

.free(addr) ⇒ Object

Free the memory at address addr



49
50
51
52
53
54
55
56
# File 'fiddle.c', line 49

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



23
24
25
# File 'lib/fiddle.rb', line 23

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



28
29
30
31
# File 'lib/fiddle.rb', line 28

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.



20
21
22
23
24
25
26
# File 'fiddle.c', line 20

static VALUE
rb_fiddle_malloc(VALUE self, VALUE size)
{
    void *ptr;
    ptr = (void*)ruby_xcalloc(1, NUM2SIZET(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.



35
36
37
38
39
40
41
42
# File 'fiddle.c', line 35

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

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

.win32_last_errorObject

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



12
13
14
# File 'lib/fiddle.rb', line 12

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



17
18
19
# File 'lib/fiddle.rb', line 17

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