Разработка и подключение библиотек двоичных форматов

Помимо специализированных типов MQL-программ — экспертов, индикаторов, скриптов и сервисов — платформа MetaTrader 5 позволяет создавать и подключать независимые двоичные модули с произвольной функциональностью, откомпилированные в виде ex5-файлов или общеупотребительных dll-библиотек (Dynamic Link Library), стандартных для Windows. Это могут быть аналитические алгоритмы, графическая визуализация, сетевое взаимодействие с веб-сервисами, управление внешними программами или самой операционной системой. В любом случае подобные библиотеки работают в терминале не как самостоятельные MQL-программы, а в связке с программой какого-либо из вышеупомянутых 4-х типов.

Суть интеграции библиотеки и основной (родительской) программы заключается в том, что библиотека особым образом экспортирует, то есть объявляет доступными для использования извне, некие функции, а программа импортирует их прототипы. Именно описание прототипов — совокупность названий, списков параметров и возвращаемых значений — позволяет вызывать в коде эти функции, не имея их реализации.

Далее во время запуска MQL-программы выполняется раннее динамическое связывание — загрузка библиотеки вслед за основной программой и установление соответствий между импортированными прототипами и имеющимися в библиотеке экспортированными функциями. Установление однозначных соответствий по именам, спискам параметров и возвращаемым типам — обязательное условие успешной загрузки. Если для описания импорта хотя бы одной функции не удастся найти соответствующую экспортируемую реализацию, выполнение MQL-программы будет отменено (она завершится ошибкой на стадии запуска).

Коммуникационно-компонентная диаграмма MQL-программы с библиотеками

Коммуникационно-компонентная диаграмма MQL-программы с библиотеками

Выбирать подключаемую библиотеку при старте MQL-программы нельзя — эту связь задает разработчик при компиляции главной программы вместе с "импортами" библиотек. Однако пользователь может вручную подменить один библиотечный ex5/dll-файл на другой между стартами программы (при условии, что прототипы реализованных экспортируемых функций совпадают в библиотеках). Это можно использовать, например, для переключения языка пользовательского интерфейса, если в библиотеках содержатся строковые ресурсы с надписями. Однако чаще всего библиотеки применяются как коммерческий продукт с неким ноу-хау, которое автор не готов распространять в виде открытых заголовочных файлов.

Для программистов, пришедших в MQL5 из других сред и уже знакомых с технологией DLL, сделаем замечание относительно позднего динамического связывания, которое является одним из преимуществ DLL. Полноценное динамические подключение одной MQL-программы (или модуля DLL) к другой MQL-программе в процессе выполнения невозможно. Единственное похожее действие, которое MQL5 позволяет делать "на ходу" — связка эксперта и индикатора через iCustom или IndicatorCreate, где индикатор выступает в роли динамически подключаемой библиотеки (однако программное взаимодействие с ним придется осуществлять через API индикаторов, что означает повышенные накладные расходы на CopyBuffer, по сравнению с прямым вызовом функций через export/#import).

Отметим, что в обычных случаях, когда MQL-программа компилируется из исходных текстов без импорта внешних функций, используется статическое связывание, то есть генерируемый двоичный код напрямую обращается к вызываемым функциям, поскольку они известны в момент компиляции.

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

В данной главе мы опишем процесс создания библиотек на MQL5, экспорт и импорт функций (включая ограничения на используемые в них типы данных), а также подключение внешних (готовых) DLL-библиотек. Разработка DLL-библиотек выходит за рамки данной книги.