gpt4 book ai didi

ruby - 如何接口(interface)更复杂的共享库?

转载 作者:数据小太阳 更新时间:2023-10-29 08:04:51 28 4
gpt4 key购买 nike

我正在尝试在 Linux/Unix 系统上动态调用外部库的函数。

我在 dl 库上取得了一些成功,但只有在使用原始 C 类型并且参数按值传递时才有效:

require 'dl/import'
module LibM
extend DL::Importer
dlload 'libm.so'
extern 'double sin(double)'
end

puts LibM.sin(3.14159265358979323846 / 2) # 1.0

但是,如何使用更复杂的类型(如 C 结构)或参数是存储调用结果的指针来连接函数?

module LibX11
extend DL::Importer
dlload 'libX11.so.6'
extern 'Display *XkbOpenDisplay (char *display_name, int *event_rtrn, int *error_rtrn, int *major_in_out, int *minor_in_out, int *reason_rtrn)'
end

Display 是一个很大的结构,在event_rtrn 中存储了一些结果等。

我看过DL::CStructBuilder它看起来可以完成这项工作,但由于文档非常简短并且没有找到有效的示例,我在这里迷失了如何正确使用它。

我必须添加必须使用的标准 Ruby 1.9 模块(如果可能的话),因为禁止在目标机器上安装额外的 gem。

最佳答案

这段时间我面临着与 C 库的接口(interface)(我正在写一个 wrapper for libgtop ),我选择使用 ffi ,即 quite well documented (尽管文档有时有点过时)最重要的是,它的邮件列表中满是在你遇到麻烦时伸出援助之手的人。

所以我向您推荐一个使用 ffi 的解决方案:

require 'ffi'

module LibX11
extend FFI::Library
ffi_lib 'libX11.so.6'

# Display *XkbOpenDisplay (char *display_name, int *event_rtrn, int *error_rtrn, int *major_in_out, int *minor_in_out, int *reason_rtrn)
attach_function :XkbOpenDisplay, [:pointer, :pointer, :pointer, :pointer, :pointer, :pointer], :pointer

end

然后你必须描述Display结构布局,就像写的here :

class Display < FFI::Struct
layout :value, :double,
:other_value, :char,
...
end

然后你做这样的事情:

p1 = FFI::MemoryPointer.new(:char)
p2 = FFI::MemoryPointer.new(:int)
p3 = FFI::MemoryPointer.new(:int)
p4 = FFI::MemoryPointer.new(:int)
p5 = FFI::MemoryPointer.new(:int)
p6 = FFI::MemoryPointer.new(:int)

# write to pointer if needed, otherwise it is a null pointer
# p1.write_char('a')
# p2.write_int(1)
# ...

struct_pointer = LibX11.XkbOpenDisplay(p1, p2, p3, p4, p5, p6)

# read the struct
struct = Display.new(display_struct_pointer)
p Hash[ s.members.map { |m| [ m, s[m] ] } ]

我没有测试代码,但它应该是大致正确的。如果不是,现在让我来。


在对 ruby​​ 2.0 上的 DL 进行一些研究后,我发现它已被弃用并被 fiddle 取代,如果你不能使用 FFI,你会考虑使用它而不是 DL。 Fiddle 似乎也适用于 ruby​​ 1.9.3 和 1.9.2

关于ruby - 如何接口(interface)更复杂的共享库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15700685/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com