#ruby #perl #cextension
#ruby #perl #cextension
Вопрос:
Согласно официальной странице о ruby, расширить Ruby с помощью C проще, чем Perl. Я не сторонник (perl) XS, но я нахожу, что очень просто написать что-то быстрое и незамысловатое с помощью Inline:: C, так почему же это проще на Ruby?
Писать расширения C на Ruby проще, чем на Perl или Python, благодаря очень элегантному API для вызова Ruby из C. Сюда входят вызовы для встраивания Ruby в программное обеспечение, для использования в качестве языка сценариев. Также доступен SWIG-интерфейс.
Любые дальнейшие объяснения от тех, кто использует больше расширений C, были бы полезны.
Комментарии:
1. Я думаю, что у этого есть большой потенциал выродиться в драку гиков, и нет ничего более мелкого и бессмысленного, чем драка гиков. И, кстати, ed >> vi > emacs, Linux > FreeBSD и т.д.
2. Пока нет единого ответа — нет необходимости в ваших отвлекающих негативных предположениях.
3. Если вы хотите, чтобы это не было абсолютно субъективным, вам придется предоставить больше структуры, чем заявление на маркетинговой странице. Возможно, перефразируете вопрос? «Приведите примеры расширений C, которые легко написать с помощью Ruby»? Или, возможно, даже проще… «какой хороший учебник по расширению Ruby с помощью C?»
4. Почему? Я не хочу замалчивать вопрос.. Безусловно, на первый взгляд это имеет некоторую ценность.. В чем ценность? Почему Ruby лучше Python и Perl, когда дело доходит до написания расширений C?
5. Преимущественное право голоса за повторное открытие. Я хочу увидеть, как кто-нибудь сравнивает написание расширений на Ruby и Perl.
Ответ №1:
(Полное раскрытие, я программист на Perl)
Ruby C API, безусловно, выглядит намного приятнее, чем на Perl. Это выглядит как обычная библиотека C с функциями, которые соответствуют коду Ruby. API Perl — это путаница макросов внутри макросов внутри макросов и флагов magic threading. Использование Perl API вне ядра Perl, безусловно, является второстепенной задачей. Ruby определенно выигрывает в том, что не вызывает ужаса, от которого сжимается кишечник.
Хотя Ruby имеет лучший C API, в Perl есть лучшие руководства о том, как с ним что-либо делать. В сгенерированной документации Ruby отсутствует какое-либо связное руководство или часто вообще какой-либо описательный текст. Возможно, я ищу не в том месте, но это все, что было предложено. В отличие от этого, документация Perl API написана от руки в прозе с полезной информацией о том, что делает каждая функция. Кроме того, в core docs есть более десятка документов об использовании Perl и C. Я бы сказал, что Perl выигрывает в docs.
FFI выглядит довольно впечатляюще. Самое близкое, что есть в Perl к FFI, — это Inline:: C, который представляет собой оболочку вокруг беспорядка XS. Его основное назначение — встроить код C в вашу программу на Perl, но вы также можете использовать его для доступа к функциям библиотеки C.
Вот тривиальный пример, похожий на пример 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. Парень, для тех, кто не решался принять вопрос в такой формулировке, это именно тот ответ, который я искал. Спасибо! Я приму это через несколько дней, если не будет дано более потрясающего.
2. Ответ @nash предоставил недостающую структуру. Также FFI заинтересовал меня.
3. Сейчас есть несколько проектов FFI для Perl
4. @JoelBerger Знаешь их имена наизусть?
5. @Schwern, Дэвид Мертенс работал над этим, особенно для интеграции с PDL. На самом деле я его немного задерживаю, так как он хочет распространять некоторые библиотеки с моим проектом Alien:: Base , который все еще тормозит. Обратите внимание, что я сказал » проекты «, поскольку я не знаю, завершены ли они (и, следовательно, выпущены), но я знаю, что у него есть некоторый успех.
Ответ №2:
С помощью 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 вы также не
необходимо установить программу разработки
версии библиотек, только
версии для среды выполнения. Конечно,
библиотеки, на которые вы ссылаетесь, понадобятся
чтобы в какой-то момент он был скомпилирован,
но, скорее всего, вам не пришлось бы делать
это.
Комментарии:
1. AFAIK, аналогичные модули доступны и для Perl.
2. Я продолжаю видеть людей, которые говорят, что FFFI ОООЧЕНЬ полезны, но как они справляются с реальными сложными типами данных? Функции переноса целых чисел и значений с плавающей запятой имеют ограниченное применение.
3.какие сложные типы? https://github.com/ffi/ffi/wiki/Structs, https://github.com/ffi/ffi/wiki/Enums, https://github.com/ffi/ffi/wiki/Types