Где найти документацию и как разработать внешнюю компоненту NativeAPI для 1С 8.3 на C++

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

При решении задач высоконагруженных вычислений, интеграции со специфическим торговым или промышленным оборудованием, низкоуровневой работы с сетью или криптографией возможностей встроенного языка 1С может оказаться недостаточно. В таких ситуациях разработчики прибегают к созданию внешних компонент. Разберем основы разработки внешних компонент по современной технологии NativeAPI, ключевые интерфейсы C++, правила управления памятью и порядок внедрения компоненты в конфигурацию «1С:Предприятие 8.3».

Что такое NativeAPI и чем она отличается от COM

Ранее основным механизмом расширения возможностей платформы являлась технология COM (ActiveX). Однако она имела серьезные ограничения: привязка исключительно к операционной системе Windows, необходимость регистрации в системном реестре с правами администратора и сложности при работе на сервере под управлением Linux. Рассмотрим ключевые преимущества NativeAPI:

  1. Кроссплатформенность: скомпилированная библиотека может работать под Windows (.dll), Linux (.so), macOS (.dylib), а также на мобильных платформах.
  2. Отсутствие регистрации в системе: библиотеке не требуется regsvr32, она динамически загружается в адресное пространство процесса клиентом или сервером 1С.
  3. Работа на клиенте и сервере: компоненту можно вызывать в фоновых заданиях, серверных процедурах, толстом и тонком клиентах.

Архитектура взаимодействия: интерфейсы NativeAPI

Рассмотрим, как устроена библиотека изнутри. В официальном комплекте поставки (SDK NativeAPI) предоставляется набор заголовочных файлов C++, определяющих правила взаимодействия между платформой и библиотекой. Разберем основные компоненты взаимодействия:

  1. Экспортируемые функции C-интерфейса библиотеки:

    Библиотека должна экспортировать стандартные точки входа:

    GetClassObject — создает экземпляр компоненты и возвращает платформе указатель на интерфейс.

    DestroyObject — корректно удаляет созданный объект из памяти.

    GetClassNames — возвращает список классов, доступных в данной библиотеке.

    SetPlatformCapabilities — согласует функциональные возможности платформы и библиотеки.

  2. Интерфейс IComponentBase:

    Это основной интерфейс, который реализует C++ класс внешней компоненты. Через него платформа опрашивает свойства и вызывает методы:

    Init и Done — методы инициализации и завершения работы компоненты.

    setMemManager — передает в компоненту указатель на менеджер памяти платформы 1С.

    GetNProps, FindProp, GetPropVal, SetPropVal — управление свойствами объекта.

    GetNMethods, FindMethod, CallAsProc, CallAsFunc — вызов процедур и функций.

    RegisterExtensionAs — определяет имя, под которым объект доступен во встроенном языке 1С.

  3. Интерфейс IAddInDefBase:

    Интерфейс предоставляется платформой 1С. Он позволяет компоненте отправлять асинхронные события обратно в 1С с помощью метода ExternalEvent. На стороне платформы такие сигналы обрабатываются в процедуре ОбработкаВнешнегоСобытия.

Критически важные особенности работы с памятью и типами данных

Проанализируем нюансы, которые чаще всего вызывают сбои и аварийное завершение процесса («падение» rphost или 1cv8c.exe):

  1. Выделение памяти под возвращаемые значения (IMemoryManager):

    Все строковые и двоичные данные, которые компонента возвращает в 1С, должны размещаться в памяти, выделенной через интерфейс IMemoryManager->AllocMemory. Если выделить память стандартным оператором new или функцией malloc, платформа 1С при попытке очистить память после вызова метода завершит работу с ошибкой доступа к памяти.

  2. Универсальный контейнер данных tVariant:

    Все параметры методов и значения свойств передаются через структуру tVariant. Она содержит тип данных (число, строка, булево, дата, двоичные данные) и соответствующее значение. При работе со строками платформа использует кодировку UTF-16.

  3. Особенности кодировок строк в Windows и Linux:

    В Windows тип wchar_t занимает 2 байта, тогда как в Linux — 4 байта. В SDK NativeAPI используется тип WCHAR_T (16-битный символ UTF-16), поэтому при кроссплатформенной разработке необходимо выполнять явную конвертацию между внутренними строками C++ (например, std::string UTF-8) и строками WCHAR_T*.

Упаковка внешней компоненты в архив с манифестом

Чтобы внешняя компонента могла бесшовно устанавливаться на клиентских компьютерах и серверах с разными операционными системами, соберем ZIP-архив со структурой поставки. В корень архива поместим скомпилированные файлы и файл описания MANIFEST.XML.

Посмотрим на пример структуры файла MANIFEST.XML:


<bundle name="MyCustomExtension" version="1.0">
    <component path="MyComp_win32.dll" type="native" os="Windows" arch="i386"/>
    <component path="MyComp_win64.dll" type="native" os="Windows" arch="x86_64"/>
    <component path="libMyComp_linux64.so" type="native" os="Linux" arch="x86_64"/>
</bundle>

Сформированный ZIP-архив загружается в конфигурацию в качестве объекта ОбщийМакет с типом Двоичные данные.

Подключение и вызов компоненты во встроенном языке 1С

Разберем по шагам программный код на стороне 1С для установки, подключения и вызова методов созданной компоненты:


&НаКлиенте
Процедура ПодключитьИВыполнитьКомпоненту()

    ИмяМакета = "ОбщийМакет.МояВнешняяКомпонента";
    ИмяПодключения = "CustomAddIn";

    // Установка компоненты из макета во временный каталог пользователя
    РезультатУстановки = УстановитьВнешнююКомпоненту(ИмяМакета);
    Если Не РезультатУстановки Тогда
        ВызватьИсключение "Не удалось установить внешнюю компоненту!";
    КонецЕсли;

    // Загрузка библиотеки в процесс
    РезультатПодключения = ПодключитьВнешнююКомпоненту(ИмяМакета, ИмяПодключения, ТипВнешнейКомпоненты.Native);
    Если Не РезультатПодключения Тогда
        ВызватьИсключение "Не удалось подключить внешнюю компоненту NativeAPI!";
    КонецЕсли;

    // Создание экземпляра объекта компоненты
    ОбъектКомпоненты = Новый("AddIn." + ИмяПодключения + ".MyExtensionClass");

    // Вызов метода компоненты
    ИсходныйТекст = "Тестовые данные для обработки";
    РезультатОбработки = ОбъектКомпоненты.ВыполнитьПреобразование(ИсходныйТекст);

    Сообщить("Результат из внешней компоненты: " + РезультатОбработки);

КонецПроцедуры

Отладка нативного кода

Выясним, как отлаживать C++ код при вызове из 1С:

  1. Скомпилируйте библиотеку в конфигурации Debug с генерацией отладочных символов (файлы .pdb для Windows или отладочная информация в .so для Linux).
  2. Откройте проект в вашей среде разработки (Visual Studio, CLion или VS Code).
  3. Выполните команду подключения к процессу (Attach to Process). Для клиентского вызова выберите процесс 1cv8c.exe или 1cv8.exe, а для серверного вызова — рабочий процесс сервера rphost.exe.
  4. Установите точки останова (breakpoints) в исходном коде C++ и вызовите соответствующий метод из сеанса «1С:Предприятия». Среда разработки перехватит управление в момент вызова функции.
← На главную