Связывание языков - PullRequest
       32

Связывание языков

15 голосов
/ 07 ноября 2008

Я задавал вопрос ранее о том, какой язык использовать для прототипа ИИ. Казалось, что все согласны с тем, что если я хочу, чтобы он был быстрым, мне нужно было использовать язык, такой как Java или C ++, но Python / Perl / Ruby был бы полезен для битов интерфейса.

Итак, это подводит меня к другому вопросу. Насколько легко связать эти языки вместе? И какая комбинация работает лучше всего? Итак, если бы я хотел иметь программу типа Ruby CGI, вызывающую функции C ++ или Java AI, это легко сделать? Любые указатели на то, где я ищу информацию о таких вещах? Или другая комбинация будет лучше?

Мой основной опыт написания веб-приложений начался с C ++ CGI, а затем перешел к Java-сервлетам (около 10 лет назад), а затем, после долгого перерыва в программировании, я написал немного PHP. Но у меня не было опыта написания веб-приложения на языке сценариев, который затем обращается к скомпилированному языку для битов, критичных к скорости. Так что любые советы будут приветствоваться!

Ответы [ 9 ]

14 голосов
/ 07 ноября 2008

Boost.Python предоставляет простой способ превратить код C ++ в модули Python. Это довольно зрелый и хорошо работает в моем опыте.

Например, неизбежный Hello World ...

char const* greet()
{
  return "hello, world";
}

может быть представлен Python, написав обертку Boost.Python:

#include <boost/python.hpp>

BOOST_PYTHON_MODULE(hello_ext)
{
  using namespace boost::python;
  def("greet", greet);
}

Вот и все. Были сделаны. Теперь мы можем построить это как общую библиотеку. Полученная DLL теперь видна Python. Вот пример сеанса Python:

>>> import hello_ext
>>> print hello.greet()
hello, world

(пример взят с boost.org)

9 голосов
/ 07 ноября 2008

Во-первых, мета-комментарий: я настоятельно рекомендую написать код целиком на языке высокого уровня, профилировать как сумасшедший и оптимизировать только там, где профилирование показывает, что это необходимо. Сначала оптимизируйте алгоритм, затем код, а затем подумайте о том, чтобы ввести тяжелое железо. Наличие оптимального алгоритма и чистого кода значительно облегчит ситуацию, когда / если вам потребуется переопределить язык более низкого уровня.

Если говорить о Python, IronPython / C #, вероятно, самый простой путь оптимизации.

CPython с C ++ выполним, но я нахожу, что C намного проще в обращении (но не все так просто, будучи C). Это облегчают два инструмента: cython / pyrex (для C) и shedskin (для C ++). Они компилируют Python в C / C ++, и оттуда вы можете получить доступ к библиотекам C / C ++ без особых сложностей.

Я никогда не использовал jython, но я слышал, что путь оптимизации jython / Java не так уж и плох.

6 голосов
/ 07 ноября 2008

Я согласен с идеей кодирования сначала на языке высокого уровня, таком как Python, Profiling, а затем реализации любого кода, который требует ускорения в C / C ++, и переноса его для использования на языке высокого уровня.

В качестве альтернативы boost я хотел бы предложить SWIG для создания кода, вызываемого на Python из C. Он достаточно прост в использовании и будет компилировать модули для широкого спектра языков. (Python, Ruby, Java, Lua. И многие другие) из кода C.

Процесс упаковки является полуавтоматическим, поэтому нет необходимости добавлять новые функции в базовый код C, что делает процесс работы более плавным.

5 голосов
/ 07 ноября 2008

Если вы выберете Perl, есть много ресурсов для взаимодействия с другими языками.

Инлайн :: C
Инлайн :: CPP
Инлайн :: Java

Из Встроенный :: C-Cookbook :

use Inline C => <<'END_C';

  void greet() {
    printf("Hello, world\n");
  }
END_C

greet;

С Perl 6 стало еще проще импортировать подпрограмму из кода собственной библиотеки, используя NativeCall .

use v6.c;

sub c-print ( Str() $s ){
  use NativeCall;

  # restrict the function to inside of this subroutine because printf is
  # vararg based, and we only handle '%s' based inputs here

  # it should be possible to handle more but it requires generating
  # a Signature object based on the format string and then do a
  # nativecast with that Signature, and a pointer to printf

  sub printf ( str, str --> int32 ) is native('libc:6') {}

  printf '%s', $s
}

c-print 'Hello World';

Это всего лишь простой пример, вы можете создать класс, который имеет представление Pointer, и некоторые из методов будут представлять собой C-код из библиотеки, которую вы используете. (работает только в том случае, если первый аргумент кода C является указателем, в противном случае вам придется обернуть его)

Если вам нужно, чтобы имя подпрограммы / метода Perl 6 было другим, вы можете использовать модификатор черты is symbol.

Есть также встроенные модули для Perl 6.

4 голосов
/ 07 ноября 2008

В Perl есть несколько способов использовать другие языки. Посмотрите на семейство модулей Inline :: в CPAN. Следуя советам других в этом вопросе, я напишу все это на одном динамическом языке (Perl, Python, Ruby и т. Д.), А затем оптимизирую нужные биты. С Perl и Inline :: вы можете оптимизировать на C, C ++ или Java. Или вы можете посмотреть на AI :: Prolog , который позволяет встраивать Prolog для программирования AI / Logic.

2 голосов
/ 07 ноября 2008

Вы можете создать свою программу на одном из языков более высокого уровня, например Python или Ruby, а затем вызывать модули, скомпилированные на языке более низкого уровня, для частей, которые вам нужны для исполнения. Вы можете выбрать платформу в зависимости от языка нижнего уровня, который вы хотите.

Например, если вы хотите использовать C ++ для быстрой работы, вы можете просто использовать простой Python или Ruby и вызывать DLL, скомпилированные в C ++. Если вы хотите использовать Java, вы можете использовать Jython или один из других динамических языков на платформе Java для вызова кода Java, это проще, чем маршрут C ++, потому что у вас есть общая виртуальная машина, поэтому объект Java можно использовать напрямую. в Jython или JRuby. То же самое можно сделать на платформе .Net с языками Iron и C #, хотя у вас, похоже, больше опыта работы с C ++ и Java, так что это были бы лучшие варианты.

2 голосов
/ 07 ноября 2008

Это может быть хорошим подходом, чтобы начать со скрипта и вызывать язык компиляции из этого скрипта только для более сложных задач.

Например, вызов java из скрипта ruby ​​ работает довольно хорошо.

require "java"
# The next line exposes Java's String as JString
include_class("java.lang.String") { |pkg, name| "J" + name }
s = JString.new("f")
1 голос
/ 09 ноября 2008

Если проблемный домен сложный (а проблемы с искусственным интеллектом часто могут быть трудными), то я сначала выберу язык, который выразителен или подходит для домена, а затем будет беспокоиться о его ускорении. Например, в Ruby есть примитивы метапрограммирования (способность легко проверять и изменять запущенную программу), что позволяет очень легко / интересно реализовывать определенные типы алгоритмов.

Если вы реализуете его таким образом, а затем его необходимо ускорить, то вы можете использовать бенчмаркинг / профилирование, чтобы найти узкое место и либо связать для этого скомпилированный язык, либо оптимизировать алгоритм. По моему опыту, наибольший выигрыш в производительности происходит от настройки алгоритма, а не от использования другого языка реализации.

1 голос
/ 09 ноября 2008

У меня другая точка зрения, мне повезло с интеграцией C ++ и Python для некоторой обработки видеоизображений в реальном времени.

Я бы сказал, что вы должны сопоставить язык с заданием для каждого модуля. Если вы реагируете на сеть, делайте это на Python, Python отлично справляется с сетевым трафиком. Пользовательский интерфейс: Python. Люди работают медленно, и Python отлично подходит для пользовательских интерфейсов, использующих wxPython или PyObjC на Mac или PyGTK. Если вы выполняете математику для большого количества данных, обработки сигналов или изображений ... закодируйте их на C или C ++ с помощью модульных тестов, а затем используйте SWIG , чтобы создать привязку к любому языку более высокого уровня.

Я использовал библиотеки изображений в wxWidgets в моем C ++, которые уже открыты для Python через wxPython, поэтому он был чрезвычайно мощным и быстрым. SCONS - это инструмент для сборки (например, make), который знает, что делать с файлами .ig swig.

Самый верхний уровень может быть на C или Python, у вас будет больше контроля и меньше проблем с упаковкой и развертыванием, если верхний уровень находится на C или C ++ ... но для дублирования того, что Py2EXE или Py2App дает вам на Windows или Mac (или заморозить на Linux.)

Наслаждайтесь мощью гибридного программирования! (Я называю использование нескольких языков в тесно связанном виде «гибридным», но это просто моя причуда.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...