【问题标题】:How is writing a C interface easier in Ruby than Perl?在 Ruby 中编写 C 接口比在 Perl 中更容易吗?
【发布时间】:2011-04-11 13:27:59
【问题描述】:

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

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

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

【问题讨论】:

  • 我认为这很有可能退化为一场极客之战,没有什么比极客之战更琐碎和毫无意义的了。而且,顺便说一句,ed >> vi > emacs、Linux > FreeBSD 等
  • 目前还没有一个单一的答案——不需要你分散注意力的负面猜测。
  • 如果您不希望这完全是主观的,那么您将不得不提供比营销页面上的陈述更多的结构。也许改写这个问题? “提供易于使用 Ruby 编写的 C 扩展示例”?或者甚至更简单......“用 C 扩展 Ruby 的好教程是什么?”
  • 为什么?我不想扼杀这个问题..当然它的脸有一些价值..有什么价值?在编写 C 扩展时,为什么 Ruby 比 Python 和 Perl 更好?
  • 抢先投票重新开放。我想看看有人比较用 Ruby 和 Perl 编写扩展。

标签: ruby perl cextension


【解决方案1】:

(完全公开,我是一名 Perl 程序员)

Ruby C API 看起来肯定比 Perl 的要好得多。它看起来像一个带有与 Ruby 代码相对应的函数的常规 C 库。 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 编译器编写一个包装器。

【讨论】:

  • 男孩,对于那些不愿接受这个问题的人来说,这正是我正在寻找的答案。谢谢!如果不是更棒的,我会在几天内接受它。
  • @nash 的回答提供了缺失的结构。 FFI 也引起了我的好奇心。
  • 现在有一些 Perl 的 FFI 项目
  • @JoelBerger 你知道他们的名字吗?
  • @Schwern, David Mertens 一直致力于此,尤其是与 PDL 的集成。我实际上有点阻止他,因为他想用我的Alien::Base 项目分发一些库,该项目仍在努力。请注意,我说的是项目,因为我不知道它们是否完整(并因此发布),但我知道他取得了一些成功。
【解决方案2】:

使用 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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-17
  • 2010-10-25
  • 1970-01-01
相关资源
最近更新 更多