123456789_123456789_123456789_123456789_123456789_

Module: Fiddle

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

Constant Summary

Class Attribute Summary

Class Method Summary

  • .dlopen(library) ⇒ Fiddle mod_func

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

  • .dlunwrap(addr) mod_func

    Returns the hexadecimal representation of a memory pointer address addr

  • .dlwrap(val) mod_func

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

  • .free(addr) mod_func

    Free the memory at address addr

  • .malloc(size) mod_func

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

  • .realloc(addr, size) mod_func

    Change the size of the memory allocated at the memory location addr to size bytes.

Class Attribute Details

.last_error (rw)

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

[ GitHub ]

  
# File 'ext/fiddle/lib/fiddle.rb', line 35

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

.last_error=(error) (rw)

Sets the last ::Fiddle::Error of the current executing Thread to error

[ GitHub ]

  
# File 'ext/fiddle/lib/fiddle.rb', line 40

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

.win32_last_error (rw)

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

[ GitHub ]

  
# File 'ext/fiddle/lib/fiddle.rb', line 12

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

.win32_last_error=(error) (rw)

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

[ GitHub ]

  
# File 'ext/fiddle/lib/fiddle.rb', line 17

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

.win32_last_socket_error (rw)

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

[ GitHub ]

  
# File 'ext/fiddle/lib/fiddle.rb', line 23

def self.win32_last_socket_error
  Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__]
end

.win32_last_socket_error=(error) (rw)

Sets the last win32 socket ::Fiddle::Error of the current executing Thread to error

[ GitHub ]

  
# File 'ext/fiddle/lib/fiddle.rb', line 29

def self.win32_last_socket_error= error
  Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__] = error
end

Class Method Details

.dlopen(library) ⇒ Fiddle (mod_func)

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

If nil is given for the library, 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 Handle.new for more.

[ GitHub ]

  
# File 'ext/fiddle/lib/fiddle.rb', line 60

def dlopen library
  Fiddle::Handle.new library
end

.dlunwrap(addr) (mod_func)

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"
[ GitHub ]

  
# File 'ext/fiddle/fiddle.c', line 74

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

.dlwrap(val) (mod_func)

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
[ GitHub ]

  
# File 'ext/fiddle/fiddle.c', line 93

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

.free(addr) (mod_func)

Free the memory at address addr

[ GitHub ]

  
# File 'ext/fiddle/fiddle.c', line 49

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

    ruby_xfree(ptr);
    return Qnil;
}

.malloc(size) (mod_func)

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

[ GitHub ]

  
# File 'ext/fiddle/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) (mod_func)

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.

[ GitHub ]

  
# File 'ext/fiddle/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);
}