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.0
Constant Summary
-
ALIGN_BOOL =
The alignment size of a bool
Fiddle::FFIBackend::FFITypes[Types::BOOL].alignment
-
ALIGN_CHAR =
The alignment size of a char
Fiddle::FFIBackend::FFITypes[Types::CHAR].alignment
-
ALIGN_DOUBLE =
The alignment size of a double
Fiddle::FFIBackend::FFITypes[Types::DOUBLE].alignment
-
ALIGN_FLOAT =
The alignment size of a float
Fiddle::FFIBackend::FFITypes[Types::FLOAT].alignment
-
ALIGN_INT =
The alignment size of an int
Fiddle::FFIBackend::FFITypes[Types::INT].alignment
-
ALIGN_INT16_T =
The alignment size of a int16_t
Fiddle::FFIBackend::FFITypes[Types::INT16_T].alignment
-
ALIGN_INT32_T =
The alignment size of a int32_t
Fiddle::FFIBackend::FFITypes[Types::INT32_T].alignment
-
ALIGN_INT64_T =
The alignment size of a int64_t
Fiddle::FFIBackend::FFITypes[Types::INT64_T].alignment
-
ALIGN_INT8_T =
The alignment size of a int8_t
Fiddle::FFIBackend::FFITypes[Types::INT8_T].alignment
-
ALIGN_INTPTR_T =
The alignment size of a intptr_t
Fiddle::FFIBackend::FFITypes[Types::INTPTR_T].alignment
-
ALIGN_LONG =
The alignment size of a long
Fiddle::FFIBackend::FFITypes[Types::LONG].alignment
-
ALIGN_LONG_LONG =
The alignment size of a long long
Fiddle::FFIBackend::FFITypes[Types::LONG_LONG].alignment
-
ALIGN_PTRDIFF_T =
The alignment size of a ptrdiff_t
Fiddle::FFIBackend::FFITypes[Types::PTRDIFF_T].alignment
-
ALIGN_SHORT =
The alignment size of a short
Fiddle::FFIBackend::FFITypes[Types::SHORT].alignment
-
ALIGN_SIZE_T =
The alignment size of a size_t
Fiddle::FFIBackend::FFITypes[Types::SIZE_T].alignment
-
ALIGN_SSIZE_T =
same as size_t
ALIGN_SIZE_T
-
ALIGN_UINTPTR_T =
The alignment size of a uintptr_t
Fiddle::FFIBackend::FFITypes[Types::UINTPTR_T].alignment
-
ALIGN_VOIDP =
The alignment size of a void*
Fiddle::FFIBackend::FFITypes[Types::VOIDP].alignment
-
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
Fiddle::Pointer.new(0)
-
Qfalse =
The value of
Qfalse
INT2NUM(Qfalse)
-
Qnil =
The value of
Qnil
INT2NUM(Qnil)
-
Qtrue =
The value of
Qtrue
INT2NUM(Qtrue)
-
Qundef =
The value of
Qundef
INT2NUM(Qundef)
-
RTLD_GLOBAL =
Internal use only
Add constants for backwards compat
Handle::RTLD_GLOBAL
-
RTLD_LAZY =
Internal use only
# File 'ext/fiddle/lib/fiddle.rb', line 128Handle::RTLD_LAZY
-
RTLD_NOW =
Internal use only
# File 'ext/fiddle/lib/fiddle.rb', line 129Handle::RTLD_NOW
-
RUBY_FREE =
Address of the ruby_xfree() function
Fiddle::Pointer::LibC::FREE.address
-
SIZEOF_BOOL =
size of a bool
Fiddle::FFIBackend::FFITypes[Types::BOOL].size
-
SIZEOF_CHAR =
size of a char
Fiddle::FFIBackend::FFITypes[Types::CHAR].size
-
SIZEOF_CONST_STRING =
size of a const char*
Fiddle::FFIBackend::FFITypes[Types::VOIDP].size
-
SIZEOF_DOUBLE =
size of a double
Fiddle::FFIBackend::FFITypes[Types::DOUBLE].size
-
SIZEOF_FLOAT =
size of a float
Fiddle::FFIBackend::FFITypes[Types::FLOAT].size
-
SIZEOF_INT =
size of an int
Fiddle::FFIBackend::FFITypes[Types::INT].size
-
SIZEOF_INT16_T =
size of a int16_t
Fiddle::FFIBackend::FFITypes[Types::INT16_T].size
-
SIZEOF_INT32_T =
size of a int32_t
Fiddle::FFIBackend::FFITypes[Types::INT32_T].size
-
SIZEOF_INT64_T =
size of a int64_t
Fiddle::FFIBackend::FFITypes[Types::INT64_T].size
-
SIZEOF_INT8_T =
size of a int8_t
Fiddle::FFIBackend::FFITypes[Types::INT8_T].size
-
SIZEOF_INTPTR_T =
size of a intptr_t
Fiddle::FFIBackend::FFITypes[Types::INTPTR_T].size
-
SIZEOF_LONG =
size of a long
Fiddle::FFIBackend::FFITypes[Types::LONG].size
-
SIZEOF_LONG_LONG =
size of a long long
Fiddle::FFIBackend::FFITypes[Types::LONG_LONG].size
-
SIZEOF_PTRDIFF_T =
size of a ptrdiff_t
Fiddle::FFIBackend::FFITypes[Types::PTRDIFF_T].size
-
SIZEOF_SHORT =
size of a short
Fiddle::FFIBackend::FFITypes[Types::SHORT].size
-
SIZEOF_SIZE_T =
size of a size_t
Fiddle::FFIBackend::FFITypes[Types::SIZE_T].size
-
SIZEOF_SSIZE_T =
same as size_t
SIZEOF_SIZE_T
-
SIZEOF_UCHAR =
size of a unsigned char
Fiddle::FFIBackend::FFITypes[Types::UCHAR].size
-
SIZEOF_UINT =
size of an unsigned int
Fiddle::FFIBackend::FFITypes[Types::UINT].size
-
SIZEOF_UINT16_T =
size of a uint16_t
Fiddle::FFIBackend::FFITypes[Types::UINT16_T].size
-
SIZEOF_UINT32_T =
size of a uint32_t
Fiddle::FFIBackend::FFITypes[Types::UINT32_T].size
-
SIZEOF_UINT64_T =
size of a uint64_t
Fiddle::FFIBackend::FFITypes[Types::UINT64_T].size
-
SIZEOF_UINT8_T =
size of a uint8_t
Fiddle::FFIBackend::FFITypes[Types::UINT8_T].size
-
SIZEOF_UINTPTR_T =
size of a uintptr_t
Fiddle::FFIBackend::FFITypes[Types::UINTPTR_T].size
-
SIZEOF_ULONG =
size of a unsigned long
Fiddle::FFIBackend::FFITypes[Types::ULONG].size
-
SIZEOF_ULONG_LONG =
size of a unsigned long long
Fiddle::FFIBackend::FFITypes[Types::ULONG_LONG].size
-
SIZEOF_USHORT =
size of a unsigned short
Fiddle::FFIBackend::FFITypes[Types::USHORT].size
-
SIZEOF_VOIDP =
size of a void*
Fiddle::FFIBackend::FFITypes[Types::VOIDP].size
-
VERSION =
# File 'ext/fiddle/lib/fiddle/version.rb', line 2"1.1.6.dev"
-
WINDOWS =
# File 'ext/fiddle/fiddle.c', line 483FFI::Platform.windows?
Class Attribute Summary
-
.last_error
rw
Returns the last
Error
of the current executingThread
or nil if none. -
.last_error=(error)
rw
Sets the last
Error
of the current executingThread
toerror
-
.win32_last_error
rw
Returns the last win32
Error
of the current executingThread
or nil if none. -
.win32_last_error=(error)
rw
Sets the last win32
Error
of the current executingThread
toerror
-
.win32_last_socket_error
rw
Returns the last win32 socket
Error
of the current executingThread
or nil if none. -
.win32_last_socket_error=(error)
rw
Sets the last win32 socket
Error
of the current executingThread
toerror
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
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
tosize
bytes.
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? return dlopen($1) 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)
# => 4425504880
In 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); }