При разработке торговых роботов в среде 1С:Предприятие 8.3 программисты часто сталкиваются с необходимостью взаимодействия с внешними специализированными библиотеками. Одной из самых популярных является trans2quik.dll — программный интерфейс для взаимодействия с терминалом QUIK. Основная сложность заключается в том, что данная библиотека реализована по технологии Win API и активно использует механизм обратных вызовов (callbacks), который 1С напрямую не поддерживает. В этой статье мы подробно разберем, как преодолеть эти ограничения и построить надежную систему для алгоритмической торговли.
Рассмотрим стандартную ситуацию: у нас есть DLL, написанная на языке C++ или Delphi, которая предоставляет функции для отправки транзакций и получения статусов заявок. В 1С мы можем легко вызвать простые функции через ЗагрузитьВнешнююКомпоненту, но как только библиотека пытается "вернуть" нам данные через callback (функцию обратного вызова), среда 1С не может это обработать самостоятельно. Проанализируем основные препятствия:
trans2quik.dll зачастую является 32-битной (x86). Если вы используете 64-битный клиент или сервер 1С, прямая загрузка будет невозможна.callback нужно передать в DLL адрес функции в памяти, что встроенный язык 1С делать не умеет.Самым эффективным и профессиональным способом является написание "обертки" на языке C++ или Delphi с использованием технологии Native API от 1С. Такая компонента будет служить мостом: она принимает вызовы от 1С, транслирует их в trans2quik.dll, подписывается на все необходимые события и перенаправляет их обратно в 1С через механизм ВнешнееСобытие (ExternalEvent).
Разберем пример реализации на стороне 1С, когда такая компонента уже создана. Проанализируем следующий код, который демонстрирует инициализацию соединения и подписку на получение заявок:
&НаКлиенте
Перем КомпонентаTQ;
&НаКлиенте
Процедура ПодключитьБиблиотеку(Команда)
// Загружаем нашу Native API обертку
Если ПодключитьВнешнююКомпоненту("C:\libs\transq.dll", "transq", ТипВнешнейКомпоненты.Native) Тогда
КомпонентаTQ = Новый ("Addin.transq.TRANS2QUIK");
// Загружаем оригинальную библиотеку QUIK
РезультатЗагрузки = КомпонентаTQ.LOADDLL("C:\QUIK\trans2quik.dll");
// Пытаемся соединиться с терминалом
ПутьКТерминалу = "C:\SBERBANK\QUIK";
КодВозврата = КомпонентаTQ.TRANS2QUIK_CONNECT(ПутьКТерминалу);
Сообщить("Результат подключения: " + КодВозврата);
Иначе
Сообщить("Ошибка: Компонента-обертка не найдена!");
КонецЕсли;
КонецПроцедуры
Выясним причину использования ExternalEvent. Когда терминал QUIK получает информацию о новой сделке, библиотека вызывает функцию в нашей компоненте. Компонента должна положить эти данные в очередь и инициировать событие в 1С. В 1С это обрабатывается в предопределенной процедуре ВнешнееСобытие.
&НаКлиенте
Процедура ВнешнееСобытие(Источник, Событие, Данные)
// Источник — имя нашей компоненты
// Событие — тип уведомления (например, "ORDER_STATUS")
// Данные — строка JSON с деталями сделки или заявки
Если Источник = "transq" Тогда
РассмотримПолученныеДанные(Событие, Данные);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура РассмотримПолученныеДанные(ТипСобытия, ТелоДанных)
// Для удобства передачи сложных структур данных используем JSON
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(ТелоДанных);
СтруктураДанных = ПрочитатьJSON(Чтение);
Сообщить("Событие: " + ТипСобытия + ". Статус заявки: " + СтруктураДанных.Status);
КонецПроцедуры
При работе с trans2quik.dll нам доступен широкий набор функций. Разберем наиболее важные методы, которые должна поддерживать ваша внешняя компонента:
ВнешнееСобытие.Если разработка собственной Native API компоненты кажется слишком трудоемкой, проанализируем современную альтернативу. В актуальных версиях QUIK (7.x и старше) встроен язык Lua. Мы можем написать небольшой скрипт на Lua, который будет работать внутри терминала и выполнять роль локального веб-сервера.
В этом случае схема взаимодействия будет выглядеть так:
HTTPЗапрос.Этот способ избавляет от проблем с разрядностью (так как обмен идет через сетевой протокол) и значительно упрощает отладку, так как 1С работает со стандартными объектами платформы.
Управление памятью: При передаче строк из C++ в 1С через внешнюю компоненту необходимо использовать распределитель памяти 1С (интерфейс IMemoryManager), иначе возможны утечки памяти и аварийное завершение работы программы.
Обработка JSON: Рекомендуется передавать все данные из библиотеки в 1С именно в формате JSON. Это позволяет передавать массивы сделок, сложные структуры котировок и статусы за один вызов ВнешнееСобытие, что минимизирует количество переключений контекста между DLL и 1С.
Безопасность транзакций: Помните, что терминал QUIK имеет лимиты на количество транзакций в секунду. При проектировании робота на 1С обязательно предусмотрите механизмы контроля частоты запросов, чтобы избежать блокировки со стороны брокера.
Подводя итог, можно сказать, что интеграция 1С с trans2quik.dll — задача выполнимая, требующая либо написания промежуточной компоненты-обертки, либо использования современных веб-технологий через Lua-интерфейс терминала. Выбор зависит от ваших компетенций в системном программировании и требований к скорости отклика системы.