module Fiddle
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
Constants
- ALIGN_BOOL
-
The alignment size of a bool
- ALIGN_CHAR
-
The alignment size of a char
- ALIGN_DOUBLE
-
The alignment size of a double
- ALIGN_FLOAT
-
The alignment size of a float
- ALIGN_INT
-
The alignment size of an int
- ALIGN_INT16_T
-
The alignment size of a int16_t
- ALIGN_INT32_T
-
The alignment size of a int32_t
- ALIGN_INT64_T
-
The alignment size of a int64_t
- ALIGN_INT8_T
-
The alignment size of a int8_t
- ALIGN_INTPTR_T
-
The alignment size of a intptr_t
- ALIGN_LONG
-
The alignment size of a long
- ALIGN_LONG_LONG
-
The alignment size of a long long
- ALIGN_PTRDIFF_T
-
The alignment size of a ptrdiff_t
- ALIGN_SHORT
-
The alignment size of a short
- ALIGN_SIZE_T
-
The alignment size of a size_t
- ALIGN_SSIZE_T
-
The alignment size of a ssize_t
- ALIGN_UINTPTR_T
-
The alignment size of a uintptr_t
- ALIGN_VOIDP
-
The alignment size of a void*
- BUILD_RUBY_PLATFORM
-
Platform built against (i.e. βx86_64-linuxβ, etc.)
See also RUBY_PLATFORM
- NULL
- Qfalse
-
The value of
Qfalse - Qnil
-
The value of
Qnil - Qtrue
-
The value of
Qtrue - Qundef
-
The value of
Qundef - RUBY_FREE
-
Address of the ruby_xfree() function
- SIZEOF_BOOL
-
size of a bool
- SIZEOF_CHAR
-
size of a char
- SIZEOF_CONST_STRING
-
size of a const char*
- SIZEOF_DOUBLE
-
size of a double
- SIZEOF_FLOAT
-
size of a float
- SIZEOF_INT
-
size of an int
- SIZEOF_INT16_T
-
size of a int16_t
- SIZEOF_INT32_T
-
size of a int32_t
- SIZEOF_INT64_T
-
size of a int64_t
- SIZEOF_INT8_T
-
size of a int8_t
- SIZEOF_INTPTR_T
-
size of a intptr_t
- SIZEOF_LONG
-
size of a long
- SIZEOF_LONG_LONG
-
size of a long long
- SIZEOF_PTRDIFF_T
-
size of a ptrdiff_t
- SIZEOF_SHORT
-
size of a short
- SIZEOF_SIZE_T
-
size of a size_t
- SIZEOF_SSIZE_T
-
size of a ssize_t
- SIZEOF_UCHAR
-
size of a unsigned char
- SIZEOF_UINT
-
size of an unsigned int
- SIZEOF_UINT16_T
-
size of a uint16_t
- SIZEOF_UINT32_T
-
size of a uint32_t
- SIZEOF_UINT64_T
-
size of a uint64_t
- SIZEOF_UINT8_T
-
size of a uint8_t
- SIZEOF_UINTPTR_T
-
size of a uintptr_t
- SIZEOF_ULONG
-
size of a unsigned long
- SIZEOF_ULONG_LONG
-
size of a unsigned long long
- SIZEOF_USHORT
-
size of a unsigned short
- SIZEOF_VOIDP
-
size of a void*
- VERSION
- WINDOWS
-
Returns a boolean regarding whether the host is WIN32
Public Class Methods
Source
# File bundled-src/fiddle-1.1.8/lib/fiddle.rb, line 79 def dlopen library Fiddle::Handle.new(library) rescue DLError => error case error.message 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 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
Source
VALUE
rb_fiddle_ptr2value(VALUE self, VALUE addr)
{
return (VALUE)NUM2PTR(addr);
}
Returns the Ruby object stored at the memory address addr
Example:
x = Object.new # => #<Object:0x0000000107c7d870> Fiddle.dlwrap(x) # => 4425504880 Fiddle.dlunwrap(_) # => #<Object:0x0000000107c7d870>
Source
static VALUE
rb_fiddle_value2ptr(VALUE self, VALUE val)
{
return PTR2NUM((void*)val);
}
Returns the memory address of the Ruby object stored at val
Example:
x = Object.new # => #<Object:0x0000000107c7d870> Fiddle.dlwrap(x) # => 4425504880
In the case val is not a heap allocated object, this method will return the tagged pointer value.
Example:
Fiddle.dlwrap(123) # => 247
Source
VALUE
rb_fiddle_free(VALUE self, VALUE addr)
{
void *ptr = NUM2PTR(addr);
ruby_xfree(ptr);
return Qnil;
}
Free the memory at address addr
Source
# File bundled-src/fiddle-1.1.8/lib/fiddle.rb, line 14 def self.last_error FFI.errno end
Source
# File bundled-src/fiddle-1.1.8/lib/fiddle.rb, line 18 def self.last_error=(error) FFI.errno = error || 0 end
Source
static VALUE
rb_fiddle_malloc(VALUE self, VALUE size)
{
void *ptr;
ptr = (void*)ruby_xcalloc(1, NUM2SIZET(size));
return PTR2NUM(ptr);
}
Allocate size bytes of memory and return the integer memory address for the allocated memory.
Source
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);
}
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.
Source
# File bundled-src/fiddle-1.1.8/lib/fiddle.rb, line 24 def win32_last_error FFI.errno.nonzero? end
Source
# File bundled-src/fiddle-1.1.8/lib/fiddle.rb, line 27 def win32_last_error=(error) FFI.errno = error || 0 end
Source
# File bundled-src/fiddle-1.1.8/lib/fiddle.rb, line 31 def win32_last_socket_error FFI.errno.nonzero? end
Source
# File bundled-src/fiddle-1.1.8/lib/fiddle.rb, line 34 def win32_last_socket_error=(error) FFI.errno = error || 0 end
Private Instance Methods
Source
# File bundled-src/fiddle-1.1.8/lib/fiddle.rb, line 79 def dlopen library Fiddle::Handle.new(library) rescue DLError => error case error.message 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 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