Как собрать внешнюю компоненту 1С (Native API) в командной строке с помощью cl.exe или g++?

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

Разработка внешних компонент (ВК) для 1С по технологии Native API традиционно ассоциируется с использованием Microsoft Visual Studio. Однако современные рабочие процессы часто требуют ухода от тяжелых IDE в сторону легковесных редакторов вроде VS Code или настройки процессов CI/CD, где сборка должна происходить в консоли. Основная трудность заключается в том, что DLL, собранная простым вызовом компилятора "по умолчанию", часто отказывается подключаться к 1С. В этой статье мы подробно разберем, как правильно настроить линковщик и компилятор, чтобы ваша компонента успешно распознавалась платформой.

Выясним причину проблемы: почему 1С не видит компоненту?

Проанализируем ситуацию: когда мы пишем код на C++, компилятор выполняет так называемое «декорирование» или «манглинг» (name mangling) имен функций. Это процесс добавления служебных символов к названию функции (например, @, _ или суффиксов с размером аргументов), чтобы обеспечить поддержку перегрузки функций. Однако 1С ожидает увидеть в DLL строго определенные точки входа с «чистыми» именами:

Если линковщик изменит имя GetClassObject на _GetClassObject@12, платформа просто не найдет нужную функцию и выдаст ошибку при попытке загрузки компоненты. Наша задача — заставить компилятор сохранить имена в первозданном виде.

Решение 1: Сборка через MSVC (cl.exe)

Рассмотрим пошагово процесс сборки с использованием инструментов Microsoft. Для корректной работы нам понадобится не только сам компилятор cl.exe, но и специальный DEF-файл. Это наиболее надежный способ управления экспортом функций.

Шаг 1: Создание DEF-файла

Создадим файл, например component.def, и пропишем в нем секцию экспорта. Это гарантирует, что линковщик не исказит имена:


LIBRARY "my_component"
EXPORTS
    GetClassNames @1
    GetClassObject @2
    DestroyObject @3

Шаг 2: Компиляция и линковка

Теперь разберем ключи командной строки. Нам нужно определить макросы для Windows и указать путь к заголовочным файлам SDK 1С. Типовая команда для сборки будет выглядеть следующим образом:


cl.exe /O2 /EHsc /MT /D "_WINDOWS" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /I"path_to_1c_sdk" /LD my_component.cpp /link /DEF:component.def /OUT:my_component.dll

Разберем основные флаги подробнее:

Решение 2: Сборка через g++ (MinGW/GCC)

Если вы предпочитаете использовать инструменты GNU (например, в VS Code под Windows через MinGW), подход немного изменится. Здесь важно учитывать соглашение о вызовах, особенно для 32-битных систем.

Проанализируем необходимые флаги для g++:


g++ -O2 -shared -static -static-libgcc -static-libstdc++ -Wl,--kill-at -D_UNICODE -I"path_to_1c_sdk" -o my_component.dll my_component.cpp

Посмотрим на специфические параметры:

Кросс-компиляция из Linux для Windows

Иногда возникает задача собрать Windows-версию компоненты, находясь в ОС Linux. Это возможно с помощью кросс-компиляторов (например, x86_64-w64-mingw32-g++). Однако здесь кроется подвох, о котором часто забывают: регистрозависимость файловой системы.

Выясним причину возможных ошибок: в коде SDK 1С заголовочные файлы могут подключаться как #include "ComponentBase.h". Если на диске файл называется componentbase.h (в нижнем регистре), компилятор на Linux выдаст ошибку, в то время как Windows проигнорировала бы это различие. Перед сборкой убедитесь, что регистр имен файлов в #include и в файловой системе полностью совпадает.

Также не забывайте про разрядность. 32-битный "Тонкий клиент" 1С никогда не загрузит 64-битную компоненту. Вам необходимо собирать две версии DLL (x86 и x64) и упаковывать их в один ZIP-архив с файлом MANIFEST.XML для корректной установки в систему.

Проверка результата с помощью системных утилит

После сборки крайне полезно проверить, что получилось "внутри" файла. Если вы используете инструменты Microsoft, воспользуйтесь утилитой dumpbin:


dumpbin /exports my_component.dll

В выводе этой команды вы должны увидеть список функций в секции exports. Если там присутствуют странные символы вроде ?GetClassObject@@... или _GetClassObject@12, значит, ключи линковщика не сработали, и 1С не сможет работать с этой библиотекой. В идеальном случае вы должны увидеть просто GetClassObject.

Подведем итог: секрет успешной сборки внешней компоненты в командной строке заключается не в самом коде C++, а в строгом управлении таблицей экспорта DLL и правильном выборе способа линковки runtime-библиотек. Используя DEF-файлы для MSVC или флаг --kill-at для GCC, вы сможете создавать стабильные и переносимые компоненты без привязки к тяжелым графическим оболочкам разработки.

← На главную