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

Eva*_*oll 8 ruby perl cextension

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

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

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

Sch*_*ern 12

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

Ruby的C API肯定看起来比好得多的Perl的.它看起来像一个常规的C库,其函数与Ruby代码相对应.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();
Run Code Online (Sandbox Code Playgroud)

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

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

此外,FFI可以平滑各种Ruby实现的可移植性问题以及它们调用本机API的不同方式.这是Inline :: C不必做的事情,坦率地说如果它确实有效的话它会很棒.一个好处是FFI接口比Inline :: C更平滑.使用Inline :: C,很明显你正在编写一个围绕C编译器的包装器.


Vas*_*ich 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}"
Run Code Online (Sandbox Code Playgroud)

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

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

  • 我一直看到那些说FFI很有用的人,但他们如何利用真实世界的复杂数据类型呢?整数和浮点值的包装函数仅用于有限的用途. (2认同)
  • 什么复杂的类型?[https://github.com/ffi/ffi/wiki/Structs](https://github.com/ffi/ffi/wiki/Structs),[https://github.com/ffi/ffi/wiki/枚举](https://github.com/ffi/ffi/wiki/Enums),[https://github.com/ffi/ffi/wiki/Types](https://github.com/ffi/ffi/维基/类型) (2认同)