8

根据官方 ruby​​ About 页面,使用 C 扩展 Ruby 比使用 Perl 更容易。我不是(perl)XS 专家,但我发现使用Inline::C快速简单地编写一些东西非常简单,那么为什么在 Ruby 中更容易呢?

用 Ruby 编写 C 扩展比用 Perl 或 Python 更容易,它有一个非常优雅的 API 可以从 C 调用 Ruby。这包括调用将 Ruby 嵌入到软件中,用作脚本语言。SWIG 接口也可用。

那些做更多 C 扩展的人的任何进一步解释都是有用的。

4

2 回答 2

12

(完全披露,我是一名 Perl 程序员)

Ruby C API看起来肯定比Perl的要好得多。它看起来像一个带有与 Ruby 代码相对应的函数的常规 C 库。Perl 的 API 是宏中宏中的宏和魔术线程标志的混乱。在 Perl 核心之外使用 Perl API 肯定是次要问题。Ruby 绝对不会因为肠子紧紧地吓人而获胜。

虽然 Ruby 有更好的 C API,但 Perl 有更好的关于如何使用它的教程。生成的 Ruby 文档缺少任何类型的连贯教程,或者通常根本没有任何描述性文本。有可能我找错了地方,但仅此而已。相比之下,Perl API 文档是手写的散文,其中包含有关每个函数作用的有用信息。此外,核心文档中有十多个关于使用 Perl 和 C 的文档。我会说 Perl 在文档上胜出。

FFI 看起来相当令人印象深刻。Perl 与 FFI 最接近的东西是Inline::C,它是 XS 混乱的包装器。它的主要用途是将C 代码内联到您的 Perl 程序中,但您也可以使用它来访问 C 库函数

这是一个类似于 nash 的 getpid 示例的简单示例。

use Inline
  C             => Config       =>
  ENABLE        => "AUTOWRAP";

use Inline C => q{ int getpid(); };

print getpid();

现在,我在作弊,因为从技术上讲 getpid 在我的系统上返回 pid_t ,但这只是一个整数。FFI 似乎有很多用于 getpid 的特殊大小写代码,所以我怀疑它的易用性将直接对应于 FFI 是否已经处理过它。琐碎的例子是微不足道的。看看当出现典型的复杂情况时会发生什么会很有趣,例如返回预分配内存并具有奇数类型和抛出结构的函数。

虽然 FFI 和 Inline::C 可以用来做同样的事情,但它们的做事方式看起来非常非常不同。Inline::C 实际上是在编译和缓存 C 代码。FFI 不知何故没有进行任何编译。我不确定这是否真的如此,或者是否在安装公共库时为您完成了编译。

此外,FFI 解决了各种 Ruby 实现及其调用本机 API 的不同方式之间的可移植性问题。这是 Inline::C 不必做的事情,坦率地说,如果它真的有效,那就太棒了。一个好处是 FFI 界面比 Inline::C 更流畅。使用 Inline::C,很明显您正在为 C 编译器编写一个包装器。

于 2011-04-11T05:27:59.080 回答
6

使用 FFI,使用 C 扩展 Ruby 非常容易。这是来自github的示例

require 'rubygems'
require 'ffi'
module Foo
  extend FFI::Library
  ffi_lib FFI::Library::LIBC
  attach_function :getpid, [ ], :int
end
puts "My pid=#{Foo.getpid}"

您不需要在系统上安装编译器即可运行 FFI 扩展。在 linux 上,您也不需要安装库的开发版本,只需安装运行时版本。当然,您链接的库需要在某个时候进行编译,但您可能不必这样做。

https://github.com/ffi/ffi/wiki/why-use-ffi

于 2011-04-10T07:13:01.537 回答