如何在Ruby中编写C接口比Perl更容易?

时间:2011-04-09 23:45:29

标签: ruby perl cextension

根据official ruby About page,使用C语言扩展Ruby比使用Perl更容易。我不是(perl)XS的人,但我觉得用Inline::C快速简单地写一些东西很简单,那么为什么Ruby中更容易呢?

  

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

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

2 个答案:

答案 0 :(得分:12)

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

Ruby C API肯定比Perl更好看。它看起来像一个常规的C库,其函数与Ruby代码相对应。 Perl的API是宏中的宏和魔术线程标记中的一堆宏。在Perl核心之外使用Perl API肯定是次要问题。 Ruby肯定会因为没有令人伤心的可怕而获胜。

虽然Ruby有一个更好的C API,但Perl有更好的教程如何使用它做任何事情。生成的Ruby文档缺少任何类型的内聚教程或根本没有任何描述性文本。我可能在错误的地方找but that's all that was offered。相比之下,Perl API文档是手写的散文,包含有关每个函数的功能的有用信息。另外,there's over a dozen documents in the core docs about using Perl and C。我会说Perl在文档上获胜。

FFI看起来非常令人印象深刻。 Perl与FFI最接近的是Inline::C,它是XS混乱的包装器。它的主要用途是inline C code into your Perl program,但您也可以将其用于access C library functions

这是一个类似于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编译器的包装器。

答案 1 :(得分: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