Разработка и Конфигурация · 11 мин
Как сделать внешнюю компоненту для 1С
Как разработать внешнюю компоненту для 1С по технологии Native API: структура проекта на C++, регистрация методов, подключение в конфигурации и типичные ошибки.
Внешняя компонента для 1С — это динамическая библиотека (DLL для Windows, SO для Linux), которая расширяет возможности платформы: работа с оборудованием, шифрование, интеграция с нестандартными API, вычисления, которые неудобно или медленно выполнять на встроенном языке. Платформа 1С:Предприятие поддерживает два механизма создания компонент: устаревший COM-подход и современную технологию Native API, которую фирма «1С» рекомендует для всех новых разработок.
Native API — это открытый интерфейс на C++, описанный в заголовочных файлах, которые поставляются вместе с платформой. Компонента, собранная по этой технологии, работает и на тонком, и на толстом клиенте, и на сервере 1С, а также может использоваться в веб-клиенте через расширение работы с файлами. Именно Native API рассматривается в этом материале как основной вариант.
Для разработки понадобятся: компилятор C++ (Visual Studio для Windows или GCC/Clang для Linux), заголовочные файлы Native API из каталога платформы, базовое понимание работы с указателями и памятью. Глубокое знание C++ не требуется — интерфейс компоненты предельно прост, основная сложность обычно заключается в прикладной логике самой библиотеки.
Когда внешняя компонента действительно нужна
Прежде чем браться за C++, стоит убедиться, что задача не решается штатными средствами. Компонента оправдана, когда нужно: работать с оборудованием через vendor-библиотеки (сканеры, ККТ с нестандартным протоколом, весы), выполнять криптографические операции, не покрытые платформой, обращаться к нативным API операционной системы, ускорить ресурсоёмкие вычисления, интегрироваться со сторонними SDK, поставляемыми только в виде бинарных библиотек.
Если задача — вызвать HTTP-сервис, разобрать JSON или выполнить запрос к базе, внешняя компонента не нужна: всё это платформа делает встроенными средствами. Лишняя нативная библиотека — это дополнительная точка отказа, необходимость поддержки сборок под разные ОС и архитектуры, а также риски безопасности.
Нужна ли компонента
Подготовка инструментов и структуры проекта
Заголовочные файлы Native API находятся в каталоге установки платформы (обычно подкаталог с подпиской ITS или в составе дистрибутива технологической платформы). Ключевые файлы: ComponentBase.h, AddInDefBase.h, IMemory.h и вспомогательные типы. Их нужно подключить к проекту и указать пути в настройках компилятора.
Минимальный проект состоит из одного класса, наследующего IComponentBase, и точек входа — функций GetClassObject и DestroyObject, которые платформа вызывает при загрузке библиотеки. Удобно сразу заложить структуру: отдельный файл с реализацией интерфейса, отдельный — с прикладной логикой, чтобы код интеграции с 1С не смешивался с бизнес-логикой.
Реализация интерфейса IComponentBase
Класс компоненты обязан реализовать набор виртуальных методов. Ключевые из них: Init (получение указателя на интерфейс соединения с платформой), RegisterExtensionAs (регистрация имени компоненты, под которым она будет видна в 1С), GetNProps и GetNMethods (количество свойств и методов), GetPropName/GetMethodName (их имена на русском и английском языках), CallAsProc и CallAsFunc (выполнение методов), GetPropVal/SetPropVal (работа со свойствами).
Обмен данными с платформой идёт через структуру tVariant — аналог VARIANT в COM. Она поддерживает числа, строки, булевы значения, даты и двоичные данные. Строки передаются в кодировке WCHAR_T (UTF-16 или UTF-32 в зависимости от платформы), поэтому для текстовых полей потребуется корректная конвертация из внутреннего представления вашей библиотеки.
Память для строк, возвращаемых в 1С, выделяется через интерфейс IMemoryManager, указатель на который передаётся в Init. Выделять память обычным malloc и передавать её платформе нельзя — это приведёт к падению процесса при освобождении.
Пример каркаса компоненты
Ниже упрощённый скелет класса компоненты с одним методом. В реальном проекте добавляются обработка ошибок, логирование и собственно полезная логика.
class CMyAddIn : public IComponentBase {
public:
CMyAddIn() : m_iConnect(nullptr), m_iMemory(nullptr) {}
bool Init(void* pConnection) override {
m_iConnect = (IAddInDefBase*)pConnection;
return m_iConnect != nullptr;
}
long GetNMethods() override { return 1; }
bool GetMethodName(const long lMethodNum, const long lMethodAlias,
WCHAR_T** wsMethodName) override {
const wchar_t* name = L"GetVersion";
// выделение памяти через IMemoryManager и копирование имени
return true;
}
bool CallAsFunc(const long lMethodNum, tVariant* pvarRetValue,
tVariant* paParams, const long lSizeArray) override {
// lMethodNum == 0 -> вернуть строку версии в pvarRetValue
return true;
}
// ... остальные обязательные методы
};
Функции-точки входа выглядят так: GetClassObject создаёт экземпляр класса по запрошенному имени, DestroyObject освобождает его. Обе экспортируются из DLL с соглашением вызовов, ожидаемым платформой.
extern "C" long GetClassObject(const WCHAR_T* wsName, IComponentBase<strong> pInterface); extern "C" long DestroyObject(IComponentBase</strong> pInterface);Сборка и упаковка компоненты
После компиляции полученная DLL сама по себе работоспособна, но для удобной установки и обновления её принято упаковывать в ZIP-архив вместе с файлом manifest.xml. Манифест описывает, какие библиотеки для каких платформ входят в поставку, и позволяет платформе автоматически выбрать нужную сборку.
Структура архива: в корне — manifest.xml, рядом — файлы библиотек (например, MyAddInWin32.dll, MyAddInWin64.dll, MyAddInLinux64.so). В манифесте для каждой библиотеки указывается атрибут code с именем файла и целевая платформа. Такой архив можно хранить в макете конфигурации и устанавливать методом УстановитьВнешнююКомпоненту из макета — это стандартный способ доставки компонент пользователям.
- 1Скомпилируйте библиотеку под каждую целевую платформу и разрядность
- 2Создайте manifest.xml с перечислением файлов и целевых платформ
- 3Упакуйте манифест и библиотеки в ZIP-архив
- 4Поместите архив в макет конфигурации типа «Двоичные данные»
- 5Проверьте установку через УстановитьВнешнююКомпоненту на чистой машине
Подключение и использование в 1С
В коде на встроенном языке компонента подключается методом ПодключитьВнешнююКомпоненту с указанием пути к файлу или макета. После успешного подключения создаётся объект: Новый("AddIn.ИмяКомпоненты"), где имя — та строка, которую компонента вернула в RegisterExtensionAs. Далее вызываются методы и читаются свойства как у обычного объекта.
Пример: ПодключитьВнешнююКомпоненту("ОбщийМакет.МояКомпонента", "МояКомп", ТипВнешнейКомпоненты.Native); Объект = Новый("AddIn.МояКомп.MyComponent"); Версия = Объект.GetVersion();. Обратите внимание: в тонком клиенте компонента исполняется на машине пользователя, в серверном вызове — на сервере, поэтому библиотека должна быть доступна и корректно работать в обоих окружениях.
Обязательно предусмотрите проверку результата подключения: метод возвращает булево значение, а при неудаче важно вывести пользователю понятное сообщение, а не падать с ошибкой создания объекта. Типичные причины неудачи — несовпадение разрядности, отсутствие зависимых библиотек ОС, блокировка антивирусом.
Как проверить результат
ПодключитьВнешнююКомпоненту вернул Истина
Возвращает Ложь или вызывает исключение — проверяйте разрядность и зависимости DLL
Методы возвращают ожидаемые значения, строки читаются полностью
Обрезанные строки, кракозябры или падение клиента — ошибки работы с памятью и кодировкой
Компонента вызывается из серверного кода без ошибок
Работает только на клиенте — на сервере нет нужной сборки или прав
Отладка и типичные проблемы
Отлаживать нативную компоненту удобнее всего, подключившись отладчиком Visual Studio к процессу 1cv8.exe и поставив точки останова внутри методов компоненты. Для этого удобно сначала собрать Debug-версию с символами. Логирование в файл изнутри компоненты тоже сильно упрощает диагностику на машинах, где отладчик недоступен.
К частым проблемам эксплуатации относятся: отсутствие Visual C++ Redistributable на машине пользователя (если библиотека собрана с динамической линковкой CRT), блокировка загрузки DLL антивирусом или политиками безопасности, конфликт версий при обновлении компоненты — старая библиотека остаётся загруженной в процессе до его перезапуска. Последнее особенно важно: обновление компоненты требует перезапуска сеанса 1С.
FAQ
Чем Native API лучше COM-компоненты?
Native API работает на всех клиентах 1С, включая Linux и веб-клиент с расширением, не требует регистрации в реестре Windows и проще в установке. COM ограничен Windows и требует административных прав для регистрации, поэтому для новых разработок фирма «1С» рекомендует именно Native API.
Можно ли написать компоненту не на C++?
Формально интерфейс можно реализовать на любом языке, способном экспортировать C-функции и работать с указателями, — например, на Delphi или Rust. На практике C++ остаётся основным вариантом, поскольку заголовочные файлы и примеры поставляются именно для него.
Почему компонента подключается на клиенте, но не работает на сервере?
Сервер 1С — отдельный процесс, часто на другой машине и под другой ОС. Проверьте, что в манифесте есть сборка под платформу сервера (например, 64-битный Linux), что она установлена в кластере и у учётной записи сервера есть права на её загрузку.
Как обновить компоненту у пользователей?
Стандартный путь — заменить ZIP-архив в макете конфигурации и вызвать УстановитьВнешнююКомпоненту при обновлении. Учтите, что уже загруженная в процесс библиотека не выгружается: пользователям потребуется перезапустить сеанс, чтобы начала использоваться новая версия.
Нужно ли подписывать компоненту цифровой подписью?
Для работы в 1С подпись не обязательна, но она снижает риск блокировки антивирусами и упрощает прохождение проверок безопасности в организациях с жёсткими политиками. Для компонент, распространяемых внешним клиентам, подпись настоятельно рекомендуется.
Что делать, если строки из компоненты приходят обрезанными?
Чаще всего причина в неверном указании длины строки или отсутствии завершающего нулевого символа при заполнении tVariant, либо в выделении памяти не через IMemoryManager. Проверьте, что память выделена методом AllocMemory интерфейса менеджера памяти и строка скопирована целиком с терминатором.
Что важно запомнить
Внешняя компонента создаётся по технологии Native API: класс C++ реализует IComponentBase, библиотека собирается под все целевые платформы, упаковывается в ZIP с manifest.xml и подключается через ПодключитьВнешнююКомпоненту. Критичны корректная работа с памятью через IMemoryManager, совпадение разрядности и тестирование только на копиях баз.