Найти тему

Скрестим ужа с ежом... То есть - C++ и Lua. А ведь симпатичная зверушка вышла

Типичная проблема. которую приходится решать. Использована картинка из моей презентации.
Типичная проблема. которую приходится решать. Использована картинка из моей презентации.

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

Думаю что любой программист, которому пришлось заниматься разработкой прикладного ПО сильнее всего настрадался при разработке того, что называется "бизнес-логикой". Как ни крути, а это, пожалуй - самое проблемное место. Именно бизнес-логика приложения хуже всего определена в ТЗ, при этом - чаще всего подвержена изменениям. А ведь каждое изменение в программе это не только изменение кода, но еще и пересборка, новый цикл тестирования, etc. В тоже время эта часть программы предъявляет наименьшие требования к производительности. Ведь компоненты бизнес-логики мало что делают сами. Они по преимуществу только отслеживают состояние системы и дают команды другим компонентам на выполнение определенных действий.

Как можно было бы упростить и облегчить себе жизнь? Прямо напрашивается очевидное решение - при написании бизнес-логики по максимуму использовать скриптовые языки, интегрируя их с другими компонентами, написанными на языках высокого уровня, в частности - на C++. Преимущества тут очевидны:

  1. Отсутствие необходимости перекомпиляции программы со всеми вытекающими...
  2. Выская скорость разработки и модификации приложения. Можно вносить изменения в текстовый файл скрипта и тут же проверять на работоспособность
  3. Значительную часть работы можно перевалить на заказчика :) Не так сложно дополнить систему каким-либо визуальным конфигуратором, который будет генерить необходимые скрипты. И пусть с его помощью клиент настраивает приложение под свои нужды - никакой специальной программерской квалификации от него не потребуется, и никаких специфических инструментов типа компилятора при этом не нужно
  4. Не буду перечислять все многочисленные преимущества такого подхода. Ограничусь только констатация факта - при разработке компьютерных игр значительная часть игровой логики реализуется именно скриптами. "Это ж-ж-ж неспроста!", как говаривал Винни-Пух

Надеюсь, что мне удалось вас убедить. Однако, давайте посмотрим, какие при этом возникают сложности, и что собственно требуется от скриптовой компоненты.

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

Второе требование - прозрачный и полный интерфейс для взаимодействия скриптовой и C++ компоненты. В реальной жизни нам понадобится двунаправленная связь, то есть возможность не только вызывать методы скрипта из С++ кода, но и обращаться к объектам и функциям C++ из скрипта. Вплоть до возможности создания объектов С++. Без этого скриптовая составляющая не сможет эффективно управлять состоянием объектов, то есть - не сможет выполнять задачи уровня бизнес логики.

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

Поскольку идеальных решений в этом мире не бывает. чем-то придется пожертвовать. Посмотрим, что именноо можно принести в жертву в нашем случае. Пусть это и не самый очевидный ответ, но мы можем смело пожертвовать функциональнстью скриптового языка. Например, такие развитые способы хранения и обработки данных, которые предоставляет Python для наших целей совершенно избыточны. Такой функционал намного эфеективнее реализовать на C++.

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

1. Возможности языка

  • Python. Создавался как самостоятельный язык программирования. Как следствие - имеет весьма развитый функционал. На этом языке вполне возможно разработать сложную и эффективную программу. Однако, для наших целей порядка 90% функционала этого языка избыточны.
  • Lua. Создавался именно как скриптовое дополнение для C/C++. По функционалу неизмеримо уступает Python, однако намного болеее заточен на взаимодействие с кодом на C/C++.

2. Легкость подключения

  • Python. Для подключения интерпретатора требуются некоторые танцы с бубном. В частности - интерпретатор Python можно подключить к программе на C++ только с помощью соответствующих компонентов BOOST. Понятно, что тащить в программу целый BOOST - не самое здоровое решение. Тем более, если мы ведем разработку встраиваемой системы, работающей в условиях дефицита ресурсов. Да и сам интерпретатор занимает весьма много места.
  • Lua. Требует всего-навсего подключения библиотеки. размером меньше 100 килобайт.

Таким образом, после сравнения всех "за" и "против" оптимальным скриптовым языком для реализации элементов бизнес логики я выбираю Lua.

В следующих статьях цикла будут рассмотрены вопросы взаимодействия Lua с кодом на C++ и даны примеры реализации некоторых паттернов проектирования с использованием скриптовой компоненты.