В этой статье мы посмотрим. как вставить в программу на C++ поддержку скриптового языка, и какую пользу можно получить от такого, на первый взгляд противоестественного, гибрида.
Думаю что любой программист, которому пришлось заниматься разработкой прикладного ПО сильнее всего настрадался при разработке того, что называется "бизнес-логикой". Как ни крути, а это, пожалуй - самое проблемное место. Именно бизнес-логика приложения хуже всего определена в ТЗ, при этом - чаще всего подвержена изменениям. А ведь каждое изменение в программе это не только изменение кода, но еще и пересборка, новый цикл тестирования, etc. В тоже время эта часть программы предъявляет наименьшие требования к производительности. Ведь компоненты бизнес-логики мало что делают сами. Они по преимуществу только отслеживают состояние системы и дают команды другим компонентам на выполнение определенных действий.
Как можно было бы упростить и облегчить себе жизнь? Прямо напрашивается очевидное решение - при написании бизнес-логики по максимуму использовать скриптовые языки, интегрируя их с другими компонентами, написанными на языках высокого уровня, в частности - на C++. Преимущества тут очевидны:
- Отсутствие необходимости перекомпиляции программы со всеми вытекающими...
- Выская скорость разработки и модификации приложения. Можно вносить изменения в текстовый файл скрипта и тут же проверять на работоспособность
- Значительную часть работы можно перевалить на заказчика :) Не так сложно дополнить систему каким-либо визуальным конфигуратором, который будет генерить необходимые скрипты. И пусть с его помощью клиент настраивает приложение под свои нужды - никакой специальной программерской квалификации от него не потребуется, и никаких специфических инструментов типа компилятора при этом не нужно
- Не буду перечислять все многочисленные преимущества такого подхода. Ограничусь только констатация факта - при разработке компьютерных игр значительная часть игровой логики реализуется именно скриптами. "Это ж-ж-ж неспроста!", как говаривал Винни-Пух
Надеюсь, что мне удалось вас убедить. Однако, давайте посмотрим, какие при этом возникают сложности, и что собственно требуется от скриптовой компоненты.
Первое пожелание - совершенно очевидно. Это полная интеграция с программой на 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++ и даны примеры реализации некоторых паттернов проектирования с использованием скриптовой компоненты.