模块 Fiddle
Ruby 的 libffi 封装器。
描述¶ ↑
Fiddle
是一个扩展,用于将外部函数接口 (FFI) 与 Ruby 转换。
它封装了 libffi,这是一个流行的 C 库,提供了一个可移植的接口,允许一种语言编写的代码调用另一种语言编写的代码。
示例¶ ↑
在这里,我们将使用 Fiddle::Function
来封装 libm 中的 floor(3)
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
-
布尔值的对齐大小
- ALIGN_CHAR
-
字符的对齐大小
- ALIGN_DOUBLE
-
双精度浮点数的对齐大小
- ALIGN_FLOAT
-
浮点数的对齐大小
- ALIGN_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
-
长整型的对齐大小
- ALIGN_LONG_LONG
-
长长整型的对齐大小
- ALIGN_PTRDIFF_T
-
ptrdiff_t 的对齐大小
- ALIGN_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
- NULL
- Qfalse
-
Qfalse
的值 - Qnil
-
Qnil
的值 - Qtrue
-
Qtrue
的值 - Qundef
-
Qundef
的值 - RUBY_FREE
-
ruby_xfree() 函数的地址
- SIZEOF_BOOL
-
布尔值的大小
- SIZEOF_CHAR
-
字符的大小
- SIZEOF_CONST_STRING
-
const char* 的大小
- SIZEOF_DOUBLE
-
双精度浮点数的大小
- SIZEOF_FLOAT
-
浮点数的大小
- SIZEOF_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
-
长整型的大小
- SIZEOF_LONG_LONG
-
长长整型的大小
- SIZEOF_PTRDIFF_T
-
ptrdiff_t 的大小
- SIZEOF_SHORT
-
短整型的大小
- SIZEOF_SIZE_T
-
size_t 的大小
- SIZEOF_SSIZE_T
-
ssize_t 的大小
- SIZEOF_UCHAR
-
无符号字符的大小
- SIZEOF_UINT
-
无符号整数的大小
- 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
-
无符号长整型的大小
- SIZEOF_ULONG_LONG
-
无符号长长整型的大小
- SIZEOF_USHORT
-
无符号短整型的大小
- SIZEOF_VOIDP
-
void* 的大小
- VERSION
- WINDOWS
-
返回一个布尔值,表示主机是否为 WIN32
公共类方法
源码
# 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.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? 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
创建一个新的处理器,打开 library
,并返回 Fiddle::Handle
的实例。
如果为 library
指定 nil
,则使用 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); }
返回存储在内存地址 addr
处的 Ruby 对象
示例
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); }
返回存储在 val
处的 Ruby 对象的内存地址
示例
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
处的内存
源码
源码
源码
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 91 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? 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
创建一个新的处理器,打开 library
,并返回 Fiddle::Handle
的实例。
如果为 library
指定 nil
,则使用 Fiddle::Handle::DEFAULT,它等效于 RTLD_DEFAULT。有关详细信息,请参阅 man 3 dlopen
。
lib = Fiddle.dlopen(nil)
默认值取决于操作系统,并为所有已加载的库提供句柄。例如,在大多数情况下,您可以使用它来访问 libc
函数,或 Ruby 函数(如 rb_str_new
)。
有关详细信息,请参阅 Fiddle::Handle.new
。