2011-04-09 23 views
8

根據official ruby About page,用C比用Perl擴展Ruby更容易。我不是一個(perl)XS傢伙,但是我發現用Inline::C寫一些簡單而快速的東西很簡單,那爲什麼Ruby更容易?在Ruby中如何在Ruby中比Perl更容易編寫C接口?

寫C語言擴展比Perl和Python更容易,有一個非常優雅的API從C.調用紅寶石這包括在軟件中嵌入紅寶石,用作腳本語言調用。 SWIG接口也可用。

從那些做更多的C擴展的任何進一步的解釋將是有用的。

+5

我覺得這有很大的潛力,退化成一個怪胎戰鬥,並沒有什麼上如此小心眼和毫無意義的怪胎鬥爭。而且,順便說一句,[編者按](http://www.gnu.org/fun/jokes/ed.msg.html)>>六>的Emacs,Linux的>的FreeBSD等 – 2011-04-10 00:21:08

+3

沒有一個單一的答案了 - - 不需要你分心的負面猜測。 – 2011-04-10 00:46:28

+4

如果您希望這只是完全主觀的東西,那麼您將不得不提供比營銷頁面上的聲明更多的結構。也許換個問題呢? 「提供易於用Ruby編寫的C擴展的例子」?或者甚至更簡單......「用C擴展Ruby的好教程是什麼?」 – Schwern 2011-04-10 01:39:57

回答

12

(全面披露,我是一個Perl程序員)

Ruby C API肯定看起來比Perl的好得多。它看起來像一個常規的C庫,其功能對應於Ruby代碼。 Perl的API是在宏和魔法線程標誌內的宏內的一團糟。在Perl核心之外使用Perl API肯定是次要的問題。紅寶石絕對是勝利,不會令人緊張恐懼。

雖然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

下面是一個與納什的getpid例子類似的簡單例子。

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

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

print getpid(); 

現在,我欺騙,因爲從技術上GETPID回報我的系統上將爲pid_t,但是這只是一個整數。 FFI似乎對getpid有很多特殊的封裝代碼,所以我懷疑它的易用性將直接對應FFI是否已經處理好它。瑣碎的例子是微不足道的。看到典型的複雜情況出現時會發生什麼,比如返回預分配內存並具有奇數類型並拋出結構的函數會很有趣。

雖然FFI和內聯:: C可被用來做同樣的事情,他們是如何做到這看起來非常,非常不同。 Inline :: C實際上是編譯和緩存C代碼。 FFI不知道如何編譯。我不確定這是真的,還是在安裝時爲通用庫編譯完成。

此外,FFI平滑跨各個Ruby實現和他們的不同調用本地API的方式可移植性問題。這是Inline :: C不需要做的事情,坦率地說,如果它真的起作用,它真是太棒了。 FFI接口的一個好處是比Inline :: C更平滑。使用Inline :: C,很明顯你正在編寫一個C編譯器的包裝器。

+0

男孩,對於那些猶豫不決接受這個問題的人來說,這正是我所尋找的答案。謝謝!我會在幾天內接受它,如果沒有給出更驚人的表現。 – 2011-04-11 05:49:16

+0

@納什的回答提供了缺失的結構。 FFI也引起了我的好奇心。 – Schwern 2011-04-11 05:51:42

+0

有一些FFI項目的Perl現在 – 2012-06-03 13:58:20

6

有了FFI它很容易紅寶石C.延伸。這是從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

+0

AFAIK,類似的模塊可用於Perl。 – 2011-04-10 10:26:54

+2

我一直看到有人說FFIs是有用的,但他們如何與現實世界的複雜數據類型相匹配?包裝整數和浮點值的功能只是有限的使用。 – tsee 2011-04-10 11:24:30

+2

什麼複雜類型? [https://github.com/ffi/ffi/wiki/Structs](https://github.com/ffi/ffi/wiki/Structs),[https://github.com/ffi/ffi/wiki/ Enums](https://github.com/ffi/ffi/wiki/Enums),[https://github.com/ffi/ffi/wiki/Types](https://github.com/ffi/ffi/ wiki/Types) – 2011-04-10 11:50:43

相關問題