На чем писать Native внешние компоненты для 1С: выбор технологий и практические примеры

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Переход платформы 1С:Предприятие на 64-битную архитектуру и кроссплатформенность (Linux, Android, macOS) поставил перед разработчиками вопрос: как переписать старые компоненты, созданные на VB6 или Delphi 7 через технологию COM? Современный стандарт Native API требует совершенно иного подхода. Проанализируем, какие инструменты актуальны сегодня и на что стоит обратить внимание при разработке.

Отличия COM от Native API

Прежде всего, разберем ключевое отличие. Если старые компоненты (COM) жестко привязаны к Windows и реестру, то Native API — это динамические библиотеки (DLL или SO), которые платформа загружает напрямую. Рассмотрим основные преимущества перехода:

Вариант 1: Классический C++

C++ остается «золотым стандартом» для написания внешних компонент. Платформа 1С сама написана на C++, и примеры на ИТС ориентированы именно на этот язык. Для разработки под Windows рекомендуется использовать последние версии Visual Studio (например, 2019 или 2022).

Разберем важный аспект работы в C++ — взаимодействие с памятью 1С. Мы не можем просто выделить память стандартными средствами, если хотим передать строку обратно в платформу. Для этого используется интерфейс IMemoryManager. Посмотрим на практический пример преобразования строки JNI (для Android) в формат, понятный 1С (WCHAR_T):


WCHAR_T* ToV8StringJni(IMemoryManager* mem, jstring jstr, int* lSize)
{
    WCHAR_T* ret = NULL;
    if (jstr)
    {
        JNIEnv *jenv = getJniEnv();
        *lSize = jenv->GetStringLength(jstr);
        const WCHAR_T* pjstr = jenv->GetStringChars(jstr, NULL);
        
        // Выделяем память через менеджер памяти 1С
        mem->AllocMemory((void**)&ret, (*lSize + 1) * sizeof(WCHAR_T));
        
        for (auto i = 0; i < *lSize; ++i)
            ret[i] = pjstr[i];
            
        ret[*lSize] = 0; // Завершающий ноль
        jenv->ReleaseStringChars(jstr, pjstr);
    }
    return ret;
}

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

Вариант 2: Использование Golang

Язык Go (Golang) становится все более популярным в среде 1С-разработчиков благодаря простому синтаксису и мощным библиотекам. Основная сложность здесь заключается в том, что Go по умолчанию не создает заголовочные файлы, совместимые с C++ интерфейсом 1С Native API напрямую.

Обычно это решается созданием небольшой «прокладки» на C++, которая вызывает функции из скомпилированной в c-shared библиотеки на Go. Однако под Linux возможности интеграции шире. Рассмотрим преимущества Go:

  1. Высокая скорость разработки.
  2. Огромное количество готовых пакетов (работа с HTTP, JSON, базами данных).
  3. Простая сборка под разные архитектуры одной командой.

Вариант 3: Delphi и Lazarus

Для тех, кто привык к синтаксису Pascal и хочет быстро перенести логику с VB6, отличным вариантом станет Lazarus. Это бесплатная среда разработки, которая позволяет компилировать нативные 64-битные библиотеки под Windows и Linux. Выясним причину его популярности: наличие готовых шаблонов Native API на GitHub, где все сложности с интерфейсами 1С уже реализованы, и вам остается только добавить свои функции.

Вариант 4: Прокси-компоненты (HTTP/gRPC/Sidecar)

Интересный подход заключается в том, чтобы написать минимальную Native-компоненту на C++, которая будет выступать лишь в роли посредника (шлюза). Основная логика при этом выносится в отдельное приложение (написанное на чем угодно — Python, C#, Node.js), которое общается с ВК через локальный HTTP-сервер или gRPC.

Разберем по шагам, как это работает:

  1. ВК на C++ при загрузке запускает фоновый процесс (ваше основное приложение).
  2. 1С вызывает метод ВК, передавая параметры.
  3. ВК упаковывает параметры в JSON и отправляет POST-запрос на localhost.
  4. Приложение обрабатывает данные и возвращает ответ.
  5. ВК передает ответ обратно в 1С.

Такой метод позволяет полностью снять ограничение на выбор языка программирования и избежать проблем с падением рабочего процесса 1С (rphost) при ошибках в коде компоненты, так как ошибка в «прокси» не затронет основной процесс.

Вариант 5: Современный Rust

Хотя в обсуждении на форуме он упоминается редко, Rust является самым современным и безопасным способом написания Native ВК. Он обеспечивает производительность C++, но предотвращает ошибки сегментации и утечки памяти на этапе компиляции. Для Rust уже существуют библиотеки (crates), такие как v8native, которые автоматизируют создание структуры ВК. Рассмотрим типичный пример вызова внешнего события из Rust:


// Примерная концепция вызова внешнего события
fn send_event(connection: &IAddInDefBaseEx, source: &str, message: &str) {
    let v8_source = to_v8_string(source);
    let v8_message = to_v8_string(message);
    unsafe {
        connection.ExternalEvent(v8_source.as_ptr(), v8_message.as_ptr(), std::ptr::null());
    }
}

Рекомендации по выбору

Выясним, какой инструмент выбрать в вашем конкретном случае:

Важный момент: при разработке под Windows всегда учитывайте, что пользователю могут понадобиться библиотеки msvcrt.dll (Visual C++ Redistributable). Старайтесь линковать библиотеку статически, чтобы компонента была самодостаточной и запускалась на любой машине без установки доп. пакетов.

Таким образом, современная разработка Native-компонент ушла далеко вперед от VB6. Мы имеем возможность выбирать инструменты под конкретную задачу, сохраняя при этом высокую производительность и стабильность системы.

← На главную