Как подключить Win API библиотеку trans2quik.dll к 1С 8.3 и реализовать торгового робота

Программист 1С v8.3 (Управляемые формы) Управленческий учет Финансы и профессиональные услуги
← На главную

При разработке торговых роботов в среде 1С:Предприятие 8.3 программисты часто сталкиваются с необходимостью взаимодействия с внешними специализированными библиотеками. Одной из самых популярных является trans2quik.dll — программный интерфейс для взаимодействия с терминалом QUIK. Основная сложность заключается в том, что данная библиотека реализована по технологии Win API и активно использует механизм обратных вызовов (callbacks), который 1С напрямую не поддерживает. В этой статье мы подробно разберем, как преодолеть эти ограничения и построить надежную систему для алгоритмической торговли.

Проблема взаимодействия 1С с Win API и механизмом Callbacks

Рассмотрим стандартную ситуацию: у нас есть DLL, написанная на языке C++ или Delphi, которая предоставляет функции для отправки транзакций и получения статусов заявок. В 1С мы можем легко вызвать простые функции через ЗагрузитьВнешнююКомпоненту, но как только библиотека пытается "вернуть" нам данные через callback (функцию обратного вызова), среда 1С не может это обработать самостоятельно. Проанализируем основные препятствия:

  1. Однопоточность 1С: Исполняемый код 1С работает в одном потоке, в то время как Win API библиотека может вызывать функции из других потоков.
  2. Разрядность: Библиотека trans2quik.dll зачастую является 32-битной (x86). Если вы используете 64-битный клиент или сервер 1С, прямая загрузка будет невозможна.
  3. Передача адресов функций: Для регистрации callback нужно передать в DLL адрес функции в памяти, что встроенный язык 1С делать не умеет.

Решение: Создание внешней компоненты Native API

Самым эффективным и профессиональным способом является написание "обертки" на языке 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 нам доступен широкий набор функций. Разберем наиболее важные методы, которые должна поддерживать ваша внешняя компонента:

Альтернативный подход: Использование Lua и HTTP

Если разработка собственной Native API компоненты кажется слишком трудоемкой, проанализируем современную альтернативу. В актуальных версиях QUIK (7.x и старше) встроен язык Lua. Мы можем написать небольшой скрипт на Lua, который будет работать внутри терминала и выполнять роль локального веб-сервера.

В этом случае схема взаимодействия будет выглядеть так:

  1. В QUIK запускается Lua-скрипт, который слушает определенный порт (например, 8080).
  2. 1С отправляет данные (команды на покупку/продажу) через стандартный объект HTTPЗапрос.
  3. Lua-скрипт принимает JSON, вызывает внутренние функции QUIK и возвращает результат в HTTP-ответе.

Этот способ избавляет от проблем с разрядностью (так как обмен идет через сетевой протокол) и значительно упрощает отладку, так как 1С работает со стандартными объектами платформы.

Важные технические нюансы

Управление памятью: При передаче строк из C++ в 1С через внешнюю компоненту необходимо использовать распределитель памяти 1С (интерфейс IMemoryManager), иначе возможны утечки памяти и аварийное завершение работы программы.

Обработка JSON: Рекомендуется передавать все данные из библиотеки в 1С именно в формате JSON. Это позволяет передавать массивы сделок, сложные структуры котировок и статусы за один вызов ВнешнееСобытие, что минимизирует количество переключений контекста между DLL и 1С.

Безопасность транзакций: Помните, что терминал QUIK имеет лимиты на количество транзакций в секунду. При проектировании робота на 1С обязательно предусмотрите механизмы контроля частоты запросов, чтобы избежать блокировки со стороны брокера.

Подводя итог, можно сказать, что интеграция 1С с trans2quik.dll — задача выполнимая, требующая либо написания промежуточной компоненты-обертки, либо использования современных веб-технологий через Lua-интерфейс терминала. Выбор зависит от ваших компетенций в системном программировании и требований к скорости отклика системы.

← На главную