2

我想创建一个调用我编写的 ac 函数的 ruby​​ gem。例如:

int func(int x)
{
  return x * 2;
}

这将在我的 ruby​​gem 的 ac 文件中。然后我希望能够通过使用 ffi 接口包装它来在 ruby​​ 中调用它:

  module TestModule
    extend FFI::Library
    ffi_lib 'MyLib'
    attach_function 'func', [:int], :int
  end

但是我不确定如何设置它,以便在安装 gem 时 c 文件将编译成一个库(名称为“MyLib”),并且 ffi 将检测该库并在上面的代码中使用它.

有谁知道如何做到这一点,或者有更好的方法吗?请注意,我宁愿不使用扩展 ruby​​ 的标准方式(如 The Pragmatic Programmer's Guide Extending Ruby 部分中所述),因为这只适用于标准 ruby​​ 解释器(我相信)。

如果这对这个问题很重要,我一直在使用珠宝商来制作我的宝石。

4

1 回答 1

5

nanothief,首先您必须咨询您的 C 编译器才能将您的 C 代码编译到库中。

例如,假设上面的函数在一个名为 MyLib.c 的文件中,并且假设您使用 GCC:

$ gcc -c MyLib.c

...导致 MyLib.o 目标文件

$ gcc -shared -o MyLib.so MyLib.o

...这会导致 MyLib.so 共享对象,这是您的库文件(但请记住,虽然此库在我的环境中可能对我来说编译得很好,但在您的环境中可能对您不起作用)。

然后,在您的 Ruby 代码中,您需要使用以下命令加载 FFI gem:

require 'ffi'

然而,使用 FFI/Ruby 方法的美妙之处在于您不需要对 gem 用户的环境做出假设。因此,在大多数情况下,您使用 ffi_lib 加载的库应该已经编译并存在于 gem 用户机器的库路径中的某个位置。

使用 C 扩展,您必须将 C 源代码与您的 gem 打包,并让您的 gem 用户自己编译 C 源代码。如果您的用户无法访问其环境的 C 编译器,或者如果他们正在使用 JRuby(仅有限支持 C 扩展,IIRC),这可能不起作用。

如果你有兴趣,你可以看看我写的这个利用 FFI 的 gem

于 2011-04-08T03:19:04.663 回答