Module: Fiddle
| Relationships & Source Files | |
| Namespace Children | |
| Modules: | |
| Classes: | |
| Exceptions: | |
| Extension / Inclusion / Inheritance Descendants | |
| Included In: | |
| Defined in: | ext/fiddle/fiddle.c, ext/fiddle/closure.c, ext/fiddle/pointer.c, ext/fiddle/lib/fiddle.rb, ext/fiddle/lib/fiddle/closure.rb, ext/fiddle/lib/fiddle/cparser.rb, ext/fiddle/lib/fiddle/ffi_backend.rb, ext/fiddle/lib/fiddle/function.rb, ext/fiddle/lib/fiddle/import.rb, ext/fiddle/lib/fiddle/pack.rb, ext/fiddle/lib/fiddle/struct.rb, ext/fiddle/lib/fiddle/types.rb, ext/fiddle/lib/fiddle/value.rb, ext/fiddle/lib/fiddle/version.rb | 
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 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.0Constant Summary
- 
    ALIGN_BOOL =
    # File 'ext/fiddle/fiddle.c', line 476The alignment size of a bool Fiddle::FFIBackend::FFITypes[Types::BOOL].alignment 
- 
    ALIGN_CHAR =
    # File 'ext/fiddle/fiddle.c', line 378The alignment size of a char Fiddle::FFIBackend::FFITypes[Types::CHAR].alignment 
- 
    ALIGN_DOUBLE =
    # File 'ext/fiddle/fiddle.c', line 440The alignment size of a double Fiddle::FFIBackend::FFITypes[Types::DOUBLE].alignment 
- 
    ALIGN_FLOAT =
    # File 'ext/fiddle/fiddle.c', line 434The alignment size of a float Fiddle::FFIBackend::FFITypes[Types::FLOAT].alignment 
- 
    ALIGN_INT =
    # File 'ext/fiddle/fiddle.c', line 390The alignment size of an int Fiddle::FFIBackend::FFITypes[Types::INT].alignment 
- 
    ALIGN_INT16_T =
    # File 'ext/fiddle/fiddle.c', line 416The alignment size of a int16_t Fiddle::FFIBackend::FFITypes[Types::INT16_T].alignment 
- 
    ALIGN_INT32_T =
    # File 'ext/fiddle/fiddle.c', line 422The alignment size of a int32_t Fiddle::FFIBackend::FFITypes[Types::INT32_T].alignment 
- 
    ALIGN_INT64_T =
    # File 'ext/fiddle/fiddle.c', line 428The alignment size of a int64_t Fiddle::FFIBackend::FFITypes[Types::INT64_T].alignment 
- 
    ALIGN_INT8_T =
    # File 'ext/fiddle/fiddle.c', line 410The alignment size of a int8_t Fiddle::FFIBackend::FFITypes[Types::INT8_T].alignment 
- 
    ALIGN_INTPTR_T =
    # File 'ext/fiddle/fiddle.c', line 464The alignment size of a intptr_t Fiddle::FFIBackend::FFITypes[Types::INTPTR_T].alignment 
- 
    ALIGN_LONG =
    # File 'ext/fiddle/fiddle.c', line 396The alignment size of a long Fiddle::FFIBackend::FFITypes[Types::LONG].alignment 
- 
    ALIGN_LONG_LONG =
    # File 'ext/fiddle/fiddle.c', line 403The alignment size of a long long Fiddle::FFIBackend::FFITypes[Types::LONG_LONG].alignment 
- 
    ALIGN_PTRDIFF_T =
    # File 'ext/fiddle/fiddle.c', line 458The alignment size of a ptrdiff_t Fiddle::FFIBackend::FFITypes[Types::PTRDIFF_T].alignment 
- 
    ALIGN_SHORT =
    # File 'ext/fiddle/fiddle.c', line 384The alignment size of a short Fiddle::FFIBackend::FFITypes[Types::SHORT].alignment 
- 
    ALIGN_SIZE_T =
    # File 'ext/fiddle/fiddle.c', line 446The alignment size of a size_t Fiddle::FFIBackend::FFITypes[Types::SIZE_T].alignment 
- 
    ALIGN_SSIZE_T =
    # File 'ext/fiddle/fiddle.c', line 452same as size_t ALIGN_SIZE_T
- 
    ALIGN_UINTPTR_T =
    # File 'ext/fiddle/fiddle.c', line 470The alignment size of a uintptr_t Fiddle::FFIBackend::FFITypes[Types::UINTPTR_T].alignment 
- 
    ALIGN_VOIDP =
    # File 'ext/fiddle/fiddle.c', line 372The alignment size of a void* Fiddle::FFIBackend::FFITypes[Types::VOIDP].alignment 
- 
    BUILD_RUBY_PLATFORM =
    # File 'ext/fiddle/fiddle.c', line 670Platform built against (i.e. “x86_64-linux”, etc.) See also RUBY_PLATFORM rb_str_new2(RUBY_PLATFORM) 
- 
    NULL =
    # File 'ext/fiddle/pointer.c', line 887A NULL pointer Fiddle::Pointer.new(0) 
- 
    Qfalse =
    # File 'ext/fiddle/fiddle.c', line 688The value of QfalseINT2NUM(Qfalse) 
- 
    Qnil =
    # File 'ext/fiddle/fiddle.c', line 694The value of QnilINT2NUM(Qnil) 
- 
    Qtrue =
    # File 'ext/fiddle/fiddle.c', line 682The value of QtrueINT2NUM(Qtrue) 
- 
    Qundef =
    # File 'ext/fiddle/fiddle.c', line 700The value of QundefINT2NUM(Qundef) 
- 
    RTLD_GLOBAL =
    Internal use only
    # File 'ext/fiddle/lib/fiddle.rb', line 131Add constants for backwards compat Handle::RTLD_GLOBAL 
- 
    RTLD_LAZY =
    Internal use only
    
 # File 'ext/fiddle/lib/fiddle.rb', line 132Handle::RTLD_LAZY 
- 
    RTLD_NOW =
    Internal use only
    
 # File 'ext/fiddle/lib/fiddle.rb', line 133Handle::RTLD_NOW 
- 
    RUBY_FREE =
    # File 'ext/fiddle/fiddle.c', line 662Address of the ruby_xfree() function Fiddle::Pointer::LibC::FREE.address 
- 
    SIZEOF_BOOL =
    # File 'ext/fiddle/fiddle.c', line 656size of a bool Fiddle::FFIBackend::FFITypes[Types::BOOL].size 
- 
    SIZEOF_CHAR =
    # File 'ext/fiddle/fiddle.c', line 498size of a char Fiddle::FFIBackend::FFITypes[Types::CHAR].size 
- 
    SIZEOF_CONST_STRING =
    # File 'ext/fiddle/fiddle.c', line 650size of a const char* Fiddle::FFIBackend::FFITypes[Types::VOIDP].size 
- 
    SIZEOF_DOUBLE =
    # File 'ext/fiddle/fiddle.c', line 614size of a double Fiddle::FFIBackend::FFITypes[Types::DOUBLE].size 
- 
    SIZEOF_FLOAT =
    # File 'ext/fiddle/fiddle.c', line 608size of a float Fiddle::FFIBackend::FFITypes[Types::FLOAT].size 
- 
    SIZEOF_INT =
    # File 'ext/fiddle/fiddle.c', line 522size of an int Fiddle::FFIBackend::FFITypes[Types::INT].size 
- 
    SIZEOF_INT16_T =
    # File 'ext/fiddle/fiddle.c', line 572size of a int16_t Fiddle::FFIBackend::FFITypes[Types::INT16_T].size 
- 
    SIZEOF_INT32_T =
    # File 'ext/fiddle/fiddle.c', line 584size of a int32_t Fiddle::FFIBackend::FFITypes[Types::INT32_T].size 
- 
    SIZEOF_INT64_T =
    # File 'ext/fiddle/fiddle.c', line 596size of a int64_t Fiddle::FFIBackend::FFITypes[Types::INT64_T].size 
- 
    SIZEOF_INT8_T =
    # File 'ext/fiddle/fiddle.c', line 560size of a int8_t Fiddle::FFIBackend::FFITypes[Types::INT8_T].size 
- 
    SIZEOF_INTPTR_T =
    # File 'ext/fiddle/fiddle.c', line 638size of a intptr_t Fiddle::FFIBackend::FFITypes[Types::INTPTR_T].size 
- 
    SIZEOF_LONG =
    # File 'ext/fiddle/fiddle.c', line 534size of a long Fiddle::FFIBackend::FFITypes[Types::LONG].size 
- 
    SIZEOF_LONG_LONG =
    # File 'ext/fiddle/fiddle.c', line 547size of a long long Fiddle::FFIBackend::FFITypes[Types::LONG_LONG].size 
- 
    SIZEOF_PTRDIFF_T =
    # File 'ext/fiddle/fiddle.c', line 632size of a ptrdiff_t Fiddle::FFIBackend::FFITypes[Types::PTRDIFF_T].size 
- 
    SIZEOF_SHORT =
    # File 'ext/fiddle/fiddle.c', line 510size of a short Fiddle::FFIBackend::FFITypes[Types::SHORT].size 
- 
    SIZEOF_SIZE_T =
    # File 'ext/fiddle/fiddle.c', line 620size of a size_t Fiddle::FFIBackend::FFITypes[Types::SIZE_T].size 
- 
    SIZEOF_SSIZE_T =
    # File 'ext/fiddle/fiddle.c', line 626same as size_t SIZEOF_SIZE_T
- 
    SIZEOF_UCHAR =
    # File 'ext/fiddle/fiddle.c', line 504size of a unsigned char Fiddle::FFIBackend::FFITypes[Types::UCHAR].size 
- 
    SIZEOF_UINT =
    # File 'ext/fiddle/fiddle.c', line 528size of an unsigned int Fiddle::FFIBackend::FFITypes[Types::UINT].size 
- 
    SIZEOF_UINT16_T =
    # File 'ext/fiddle/fiddle.c', line 578size of a uint16_t Fiddle::FFIBackend::FFITypes[Types::UINT16_T].size 
- 
    SIZEOF_UINT32_T =
    # File 'ext/fiddle/fiddle.c', line 590size of a uint32_t Fiddle::FFIBackend::FFITypes[Types::UINT32_T].size 
- 
    SIZEOF_UINT64_T =
    # File 'ext/fiddle/fiddle.c', line 602size of a uint64_t Fiddle::FFIBackend::FFITypes[Types::UINT64_T].size 
- 
    SIZEOF_UINT8_T =
    # File 'ext/fiddle/fiddle.c', line 566size of a uint8_t Fiddle::FFIBackend::FFITypes[Types::UINT8_T].size 
- 
    SIZEOF_UINTPTR_T =
    # File 'ext/fiddle/fiddle.c', line 644size of a uintptr_t Fiddle::FFIBackend::FFITypes[Types::UINTPTR_T].size 
- 
    SIZEOF_ULONG =
    # File 'ext/fiddle/fiddle.c', line 540size of a unsigned long Fiddle::FFIBackend::FFITypes[Types::ULONG].size 
- 
    SIZEOF_ULONG_LONG =
    # File 'ext/fiddle/fiddle.c', line 553size of a unsigned long long Fiddle::FFIBackend::FFITypes[Types::ULONG_LONG].size 
- 
    SIZEOF_USHORT =
    # File 'ext/fiddle/fiddle.c', line 516size of a unsigned short Fiddle::FFIBackend::FFITypes[Types::USHORT].size 
- 
    SIZEOF_VOIDP =
    # File 'ext/fiddle/fiddle.c', line 492size of a void* Fiddle::FFIBackend::FFITypes[Types::VOIDP].size 
- 
    VERSION =
    
 # File 'ext/fiddle/lib/fiddle/version.rb', line 2"1.1.6"
- 
    WINDOWS =
    
 # File 'ext/fiddle/fiddle.c', line 483FFI::Platform.windows? 
Class Attribute Summary
- 
    
      .last_error  
    
    rw
    Returns the last Errorof the current executingThreador nil if none.
- 
    
      .last_error=(error)  
    
    rw
    Sets the last Errorof the current executingThreadtoerror
- 
    
      .win32_last_error  
    
    rw
    Returns the last win32 Errorof the current executingThreador nil if none.
- 
    
      .win32_last_error=(error)  
    
    rw
    Sets the last win32 Errorof the current executingThreadtoerror
- 
    
      .win32_last_socket_error  
    
    rw
    Returns the last win32 socket Errorof the current executingThreador nil if none.
- 
    
      .win32_last_socket_error=(error)  
    
    rw
    Sets the last win32 socket Errorof the current executingThreadtoerror
Class Method Summary
- 
    
      .dlopen(library)  ⇒ Fiddle 
    
    mod_func
    Creates a new handler that opens library, and returns an instance ofHandle.
- 
    
      .dlunwrap(addr)  
    
    mod_func
    Returns the Ruby object stored at the memory address addr
- 
    
      .dlwrap(val)  
    
    mod_func
    Returns the memory address of the Ruby object stored at val
- 
    
      .free(addr)  
    
    mod_func
    Free the memory at address addr
- 
    
      .malloc(size)  
    
    mod_func
    Allocate sizebytes 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 addrtosizebytes.
Class Attribute Details
.last_error (rw)
Returns the last ::Fiddle::Error of the current executing Thread or nil if none
# File 'ext/fiddle/lib/fiddle.rb', line 57
def self.last_error if RUBY_ENGINE == 'jruby' errno = FFI.errno errno == 0 ? nil : errno else Thread.current[:__FIDDLE_LAST_ERROR__] end end
.last_error=(error) (rw)
Sets the last ::Fiddle::Error of the current executing Thread to error
# File 'ext/fiddle/lib/fiddle.rb', line 67
def self.last_error= error if RUBY_ENGINE == 'jruby' FFI.errno = error || 0 else Thread.current[:__DL2_LAST_ERROR__] = error Thread.current[:__FIDDLE_LAST_ERROR__] = error end end
.win32_last_error (rw)
Returns the last win32 ::Fiddle::Error of the current executing Thread or nil if none
# File 'ext/fiddle/lib/fiddle.rb', line 16
def self.win32_last_error if RUBY_ENGINE == 'jruby' errno = FFI.errno errno == 0 ? nil : errno else Thread.current[:__FIDDLE_WIN32_LAST_ERROR__] end end
.win32_last_error=(error) (rw)
Sets the last win32 ::Fiddle::Error of the current executing Thread to error
# File 'ext/fiddle/lib/fiddle.rb', line 26
def self.win32_last_error= error if RUBY_ENGINE == 'jruby' FFI.errno = error || 0 else Thread.current[:__FIDDLE_WIN32_LAST_ERROR__] = error end end
.win32_last_socket_error (rw)
Returns the last win32 socket ::Fiddle::Error of the current executing Thread or nil if none
# File 'ext/fiddle/lib/fiddle.rb', line 36
def self.win32_last_socket_error if RUBY_ENGINE == 'jruby' errno = FFI.errno errno == 0 ? nil : errno else Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__] end end
.win32_last_socket_error=(error) (rw)
Sets the last win32 socket ::Fiddle::Error of the current executing Thread to error
# File 'ext/fiddle/lib/fiddle.rb', line 47
def self.win32_last_socket_error= error if RUBY_ENGINE == 'jruby' FFI.errno = error || 0 else Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__] = error end 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.
# File 'ext/fiddle/lib/fiddle.rb', line 91
def dlopen library begin Fiddle::Handle.new(library) rescue DLError => error case RUBY_PLATFORM when /linux/ case error. when /\A(\/.+?): (?:invalid ELF header|file too short)/ # This may be a linker script: # https://sourceware.org/binutils/docs/ld.html#Scripts path = $1 else raise end else raise end File.open(path) do |input| input.each_line do |line| case line when /\A\s*(?:INPUT|GROUP)\s*\(\s*([^\s,\)]+)/ # TODO: Should we support multiple files? first_input = $1 if first_input.start_with?("-l") first_input = "lib#{first_input[2..-1]}.so" end return dlopen(first_input) end end end # Not found raise end end
.dlunwrap(addr) (mod_func)
# File 'ext/fiddle/fiddle.c', line 74
VALUE
rb_fiddle_ptr2value(VALUE self, VALUE addr)
{
    return (VALUE)NUM2PTR(addr);
}
  .dlwrap(val) (mod_func)
Returns the memory address of the Ruby object stored at val
Example:
x = Object.new
# => #<Object:0x0000000107c7d870>
Fiddle.dlwrap(x)
# => 4425504880In the case val is not a heap allocated object, this method will return the tagged pointer value.
Example:
Fiddle.dlwrap(123)
# => 247# File 'ext/fiddle/fiddle.c', line 100
static VALUE
rb_fiddle_value2ptr(VALUE self, VALUE val)
{
    return PTR2NUM((void*)val);
}
  .free(addr) (mod_func)
Free the memory at address addr
# File 'ext/fiddle/fiddle.c', line 51
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.
# File 'ext/fiddle/fiddle.c', line 22
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.
# File 'ext/fiddle/fiddle.c', line 37
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);
}