Как писать интерфейс C легче в Ruby, чем в Perl? - PullRequest
8 голосов
/ 10 апреля 2011

Согласно официальной странице ruby ​​О странице расширить Ruby с помощью C легче, чем Perl. Я не (Perl) XS парень, но я считаю, что написать что-то быстро и просто с помощью Inline :: C очень просто, так почему в Ruby это проще?

Написание расширений C в Ruby проще, чем в Perl или Python, с очень элегантным API для вызова Ruby из C. Это включает в себя вызовы для встраивания Ruby в программное обеспечение для использования в качестве языка сценариев. Интерфейс SWIG также доступен.

Любое дальнейшее объяснение от тех, кто делает больше C-расширений, было бы полезно.

Ответы [ 2 ]

12 голосов
/ 11 апреля 2011

(полное раскрытие, я программист на Perl)

API Ruby C определенно выглядит намного лучше, чем Perl .Это похоже на обычную библиотеку C с функциями, которые соответствуют коду Ruby.Perl API - это беспорядок макросов в макросах внутри макросов и магические флаги потоков.Использование Perl API вне ядра Perl, безусловно, является второстепенной задачей.Ruby определенно выигрывает от того, что кишечник не пугает.

В то время как Ruby имеет лучший C API, у Perl есть лучшие учебники о том, как с этим что-то делать.В сгенерированной документации по Ruby отсутствует какое-либо связное учебное пособие или часто вообще описательный текст.Возможно, я смотрю не в том месте , но это все, что было предложено .Напротив, документация по API Perl написана от руки и содержит полезную информацию о том, что делает каждая функция.Кроме того, в основных документах содержится более десятка документов об использовании 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.

6 голосов
/ 10 апреля 2011

С помощью FFI очень легко расширить Ruby с помощью 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

...