модуль Fiddle
Обёртка libffi для Ruby.
Описание
Fiddle является расширением для преобразования интерфейса внешних функций (FFI) с использованием Ruby.
Он оборачивает libffi, популярную библиотеку C, которая предоставляет портативный интерфейс, позволяющий коду, написанному на одном языке, вызывать код, написанный на другом языке.
Пример
Здесь мы будем использовать Fiddle::Function для обертки floor(3) из 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
Константы
- ALIGN_BOOL
-
Размер выравнивания для bool
- ALIGN_CHAR
-
Размер выравнивания для char
- ALIGN_DOUBLE
-
Размер выравнивания для double
- ALIGN_FLOAT
-
Размер выравнивания для float
- ALIGN_INT
-
Размер выравнивания для int
- ALIGN_INT16_T
-
Размер выравнивания для int16_t
- ALIGN_INT32_T
-
Размер выравнивания для int32_t
- ALIGN_INT64_T
-
Размер выравнивания для int64_t
- ALIGN_INT8_T
-
Размер выравнивания для int8_t
- ALIGN_INTPTR_T
-
Размер выравнивания для intptr_t
- ALIGN_LONG
-
Размер выравнивания для long
- ALIGN_LONG_LONG
-
Размер выравнивания для long long
- ALIGN_PTRDIFF_T
-
Размер выравнивания для ptrdiff_t
- ALIGN_SHORT
-
Размер выравнивания для short
- ALIGN_SIZE_T
-
Размер выравнивания для size_t
- ALIGN_SSIZE_T
-
Размер выравнивания для ssize_t
- ALIGN_UINTPTR_T
-
Размер выравнивания для uintptr_t
- ALIGN_VOIDP
-
Размер выравнивания для void*
- BUILD_RUBY_PLATFORM
-
Платформа, для которой был скомпилирован (например, “x86_64-linux” и т.д.)
См. также RUBY_PLATFORM
- Qfalse
-
Значение
Qfalse - Qnil
-
Значение
Qnil - Qtrue
-
Значение
Qtrue - Qundef
-
Значение
Qundef - RUBY_FREE
-
Адрес функции ruby_xfree()
- SIZEOF_BOOL
-
размер bool
- SIZEOF_CHAR
-
размер char
- SIZEOF_CONST_STRING
-
размер const char*
- SIZEOF_DOUBLE
-
размер double
- SIZEOF_FLOAT
-
размер float
- SIZEOF_INT
-
размер int
- SIZEOF_INT16_T
-
размер int16_t
- SIZEOF_INT32_T
-
размер int32_t
- SIZEOF_INT64_T
-
размер int64_t
- SIZEOF_INT8_T
-
размер int8_t
- SIZEOF_INTPTR_T
-
размер intptr_t
- SIZEOF_LONG
-
размер long
- SIZEOF_LONG_LONG
-
размер long long
- SIZEOF_PTRDIFF_T
-
размер ptrdiff_t
- SIZEOF_SHORT
-
размер short
- SIZEOF_SIZE_T
-
размер size_t
- SIZEOF_SSIZE_T
-
размер ssize_t
- SIZEOF_UCHAR
-
размер unsigned char
- SIZEOF_UINT
-
размер unsigned int
- SIZEOF_UINT16_T
-
размер uint16_t
- SIZEOF_UINT32_T
-
размер uint32_t
- SIZEOF_UINT64_T
-
размер uint64_t
- SIZEOF_UINT8_T
-
размер uint8_t
- SIZEOF_UINTPTR_T
-
размер uintptr_t
- SIZEOF_ULONG
-
размер unsigned long
- SIZEOF_ULONG_LONG
-
размер unsigned long long
- SIZEOF_USHORT
-
размер unsigned short
- SIZEOF_VOIDP
-
размер void*
- VERSION
- WINDOWS
-
Возвращает булево значение, указывающее, является ли хост WIN32
Публичные методы класса
# File ext/fiddle/lib/fiddle.rb, line 60
def dlopen library
begin
Fiddle::Handle.new(library)
rescue DLError => error
case RUBY_PLATFORM
when /linux/
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
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 Создает новый обработчик, который открывает library, и возвращает экземпляр Fiddle::Handle.
Если nil задан для library, используется Fiddle::Handle::DEFAULT, что эквивалентно RTLD_DEFAULT. См. man 3 dlopen для получения дополнительной информации.
lib = Fiddle.dlopen(nil)
Значение по умолчанию зависит от ОС и предоставляет дескриптор для всех уже загруженных библиотек. Например, в большинстве случаев вы можете использовать это для доступа к функциям libc, или функциям Ruby, таким как rb_str_new.
См. Fiddle::Handle.new для получения дополнительной информации.
VALUE
rb_fiddle_ptr2value(VALUE self, VALUE addr)
{
return (VALUE)NUM2PTR(addr);
} Возвращает объект Ruby, хранящийся по адресу памяти addr
Пример:
x = Object.new # => #<Object:0x0000000107c7d870> Fiddle.dlwrap(x) # => 4425504880 Fiddle.dlunwrap(_) # => #<Object:0x0000000107c7d870>
static VALUE
rb_fiddle_value2ptr(VALUE self, VALUE val)
{
return PTR2NUM((void*)val);
} Возвращает адрес памяти объекта Ruby, хранящегося по val
Пример:
x = Object.new # => #<Object:0x0000000107c7d870> Fiddle.dlwrap(x) # => 4425504880
В случае, если val не является объектом, выделенным в куче, этот метод вернет значение помеченного указателя.
Пример:
Fiddle.dlwrap(123) # => 247
VALUE
rb_fiddle_free(VALUE self, VALUE addr)
{
void *ptr = NUM2PTR(addr);
ruby_xfree(ptr);
return Qnil;
} Освобождает память по адресу addr
# File ext/fiddle/lib/fiddle.rb, line 35 def self.last_error Thread.current[:__FIDDLE_LAST_ERROR__] end
Возвращает последнюю Error текущего выполняющегося Thread или nil, если таковой отсутствует
# 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
Устанавливает последнюю Error текущего выполняющегося Thread в error
static VALUE
rb_fiddle_malloc(VALUE self, VALUE size)
{
void *ptr;
ptr = (void*)ruby_xcalloc(1, NUM2SIZET(size));
return PTR2NUM(ptr);
} Выделяет size байт памяти и возвращает целочисленный адрес памяти для выделенной памяти.
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);
} Изменяет размер памяти, выделенной в месте памяти addr, до size байт. Возвращает адрес памяти перераспределенной памяти, который может отличаться от переданного адреса.
# File ext/fiddle/lib/fiddle.rb, line 12 def self.win32_last_error Thread.current[:__FIDDLE_WIN32_LAST_ERROR__] end
Возвращает последнюю ошибку win32 Error текущего выполняющегося Thread или nil, если таковой отсутствует
# File ext/fiddle/lib/fiddle.rb, line 17 def self.win32_last_error= error Thread.current[:__FIDDLE_WIN32_LAST_ERROR__] = error end
Устанавливает последнюю ошибку win32 Error текущего выполняющегося Thread в error
# File ext/fiddle/lib/fiddle.rb, line 23 def self.win32_last_socket_error Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__] end
Возвращает последнюю ошибку сокета win32 Error текущего выполняющегося Thread или nil, если таковой отсутствует
# File ext/fiddle/lib/fiddle.rb, line 29 def self.win32_last_socket_error= error Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__] = error end
Устанавливает последнюю ошибку сокета win32 Error текущего выполняющегося Thread в error
Приватные методы экземпляра
# File ext/fiddle/lib/fiddle.rb, line 60
def dlopen library
begin
Fiddle::Handle.new(library)
rescue DLError => error
case RUBY_PLATFORM
when /linux/
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
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 Создает новый обработчик, который открывает library, и возвращает экземпляр Fiddle::Handle.
Если nil задан для library, используется Fiddle::Handle::DEFAULT, что эквивалентно RTLD_DEFAULT. См. man 3 dlopen для получения дополнительной информации.
lib = Fiddle.dlopen(nil)
Значение по умолчанию зависит от ОС и предоставляет дескриптор для всех уже загруженных библиотек. Например, в большинстве случаев вы можете использовать это для доступа к функциям libc, или функциям Ruby, таким как rb_str_new.
См. Fiddle::Handle.new для получения дополнительной информации.
Ruby Core © 1993–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.