Как мне сделать противную программу на С ++, написанную на Python и / или Lua?

Передо мной стоит задача сделать приложение C++ доступным для скриптов пользователями. Приложение разрабатывалось в течение нескольких лет, и никто не думал об этом раньше. Он содержит все виды тонкостей, таких как многопоточность, мастерство шаблонов и множественное наследование. В качестве языка сценариев предпочтение отдается Python, но Lua может быть принят, если его значительно проще реализовать.

Вопрос 1

Из того, что я узнал до сих пор, в целом есть два способа интеграции Python/Lua с C++: "расширение" и "встраивание".

В этом случае, похоже, мне нужны оба. Язык сценариев должен иметь доступ к объектам, методам и данным из приложения, но должен вызываться приложением после того, как пользователь написал сценарий - без перезапуска чего-либо.

Как это обычно делается в реальном мире?

вопрос 2

Кажется, существует множество изумительных ручных решений и генераторов привязок, но все они не идеальны.

  • swig, pyste, Py ++, ctypes, Boost.Python sip, PyCXX, pybindgen, robin, (Cython / Pyrex, Weave)
  • CppLua, Diluculum, Luabind, Luabridge, LuaCpp, Luna / LunaWrapper, MLuaBind, MultiScript, OOLua, SLB, Sweet Lua, люкс (этот список из lua wiki)
  • КПБ, толуа, толуа ++, toLuaxx, луна и снова глоток

Большинство комментариев, найденных в Интернете, немного устарели. Например, swig считается трудным в нетривиальных случаях и генерировать непонятный код. OTOH, он недавно перешел на v2.0.

Некоторые из вышеупомянутых программ используют pygccxml, чтобы позволить gcc проанализировать код C++, а затем генерировать привязку. Я нахожу эту идею привлекательной, так как gcc, вероятно, понимает код лучше, чем я:-). Это хорошо работает?

Их тестирование может легко стоить мне половины времени, выделенного на весь проект.

Итак, какие из них вы рекомендуете?

5 ответов

Я бы не рекомендовал swig, так как трудно заставить его генерировать удовлетворительное связывание в сложных ситуациях: был там, сделал это. Мне пришлось написать ужасный сценарий, который "анализировал" исходный код C++, чтобы сгенерировать некоторый приемлемый код C++, который можно было бы жевать и генерировать приемлемые привязки. Итак, в целом: избегайте ЛЮБОГО решения, которое основано на анализе исходной программы на C++.

Между Lua и Python: я обнаружил, что Lua НАМНОГО, НАМНОГО лучше задокументирован и более четко реализован. Python имеет GIL (глобальную блокировку), тогда как с Lua, например, вы можете иметь экземпляр интерпретатора в каждом потоке. Так что, если вы можете выбрать, я бы порекомендовал Луа. Это меньший язык, его легче понять, легче внедрить (намного чище и меньше API, с отличной документацией). Я использовал luabind для небольшого проекта и нашел его простым в использовании.

Что касается вопроса 1 - да, вам нужно сделать оба.

Вы бы предоставили свой интерфейс сценариев приложений встроенному интерпретатору, который затем запускает соответствующий пользовательский сценарий.

Раздел руководств по встраиванию Python по встраиванию включает в себя раздел Расширение встраиваемого Python, а также есть учебные пособия для подобных вещей для Lua, см., Например, эту статью Конечно, возможно, есть более простые способы, когда вы определитесь с тем, какой язык сценариев и механизм связывания вы хотите использовать.

Некоторые из вышеупомянутых программ используют pygccxml, чтобы позволить gcc проанализировать код C++, а затем генерировать привязку. Я нахожу эту идею привлекательной, так как gcc, вероятно, понимает код лучше, чем я:-). Это хорошо работает?

Аналогичный подход используется в привязке Lua Qt - lqt. Оно использует cpptoxml генерировать XML-файл, содержащий все классы и методы с параметрами, и генерировать связывающий код C++ в соответствии с этим.

Он работает очень хорошо, генератор может связывать практически все классы и методы Qt, включая виртуальные методы, перегруженные операторы, выбранные классы шаблонов, механизм сигналов / слотов и т. Д.

Несмотря на то, что он был создан специально для Qt, он имеет режим "noqt", в котором он может служить общим связующим, но, к сожалению, у меня нет опыта работы с ним, поэтому я не могу сказать, сколько будет работы, чтобы связать ваш код.

Попробуйте Boost::Python, с ним связана некоторая кривая обучения, но, на мой взгляд, это лучший инструмент для работы, у нас есть огромная система реального времени и мы разработали библиотеку сценариев для QA в Boost::Python.

Мой опыт может быть небольшим, но я думаю, что он, по крайней мере, стоит того, за что вы заплатили;)

Я сделал несколько базовых модулей Python "hello world", и я не мог по-настоящему погрузиться в swig - это казалось слишком трудоемким для того, что я делал. Конечно, также возможно, что это как раз то, что вам нужно.

Другие вопросы по тегам