我想创建一个 ruby gem 来调用我编写的 ac 函数。例如:
int func(int x)
{
return x * 2;
}
Run Code Online (Sandbox Code Playgroud)
这将位于我的 rubygem 的 ac 文件中。然后我希望能够通过用 ffi 接口包装它,在 ruby 中调用它:
module TestModule
extend FFI::Library
ffi_lib 'MyLib'
attach_function 'func', [:int], :int
end
Run Code Online (Sandbox Code Playgroud)
但是我不知道如何设置它,以便当安装 gem 时,c 文件将编译成一个库(名称为“MyLib”),并且 ffi 将检测该库并在上面的代码中使用它。
有谁知道如何做到这一点,或者有更好的方法吗?请注意,我宁愿不使用扩展 ruby 的标准方法(如《实用程序员指南扩展 Ruby》部分中所述),因为这只适用于标准 ruby 解释器(我相信)。
我一直在使用珠宝商来建造我的宝石,如果这对这个问题很重要的话。
nanothief,首先您必须咨询您的 C 编译器以将您的 C 代码编译到库中。
例如,假设上面的函数位于名为 MyLib.c 的文件中,并假设您使用 GCC:
$ gcc -c MyLib.c
Run Code Online (Sandbox Code Playgroud)
...这会产生 MyLib.o 目标文件
$ gcc -shared -o MyLib.so MyLib.o
Run Code Online (Sandbox Code Playgroud)
...这会产生 MyLib.so 共享对象,这是您的库文件(但请记住,虽然这个库可能在我的环境中编译得很好,但在您的环境中可能不适用于您)。
然后,在 Ruby 代码中,您需要使用以下命令加载 FFI gem:
require 'ffi'
Run Code Online (Sandbox Code Playgroud)
然而,使用 FFI/Ruby 方法的优点在于您不需要对 gem 用户的环境做出假设。因此,在大多数情况下,使用 ffi_lib 加载的库应该已经编译并存在于 gem 用户计算机的库路径中的某个位置。
使用 C 扩展,您必须将 C 源代码与您的 gem 打包,并让您的 gem 用户自己编译 C 源代码。如果您的用户无权访问适合其环境的 C 编译器,或者他们使用 JRuby(仅对 C 扩展的支持有限,IIRC),则这可能不起作用。
如果你有兴趣,你可以看看我写的这个利用 FFI 的 gem。
| 归档时间: |
|
| 查看次数: |
1678 次 |
| 最近记录: |