Конструктор внешних компонент 1C (native API)

04.12.24

Разработка - Разработка внешних компонент

В статье описывается приложение-конструктор внешних компонент (native API). Конструктор упрощает процесс разработки за счет удобного добавления всех нужных функций и процедур в графическом режиме, с указанием их параметров и типов параметров. На выходе приложение генерирует готовый код на С++ и Rust и позволяет сразу приступить к реализации, без настройки API компоненты вручную.

Также конструктор автоматизирует интеграцию библиотек на Rust в компоненту на С++. Таким образом на С++ будет описана только базовая логика взаимодействия компоненты и платформы, а вся основная логика будет реализована в библиотеке на Rust. Этот подход выбран, так как реализовать native API на С++ проще, и также взаимодействовать с библиотекой на Rust через FFI интерфейс несложно, и мало отличается от обычного вызова методов из той же программы на С++.

Я думаю, общая идея понятна, перейду к примерам.

Используя конструктор, создам внешнюю компоненту и несколько методов.

Первый простой пример, для демонстрации общего принципа работы конструктора.

Добавлю функцию, которая просто будет возвращать строку из метода на rust.

Запущу конструктор (это приложение разработанное на tauri)

 

 

Окно приложения

 

 

На закладке Функции добавлю новую функцию

 

 

Укажу русский и английский синоним для функции. Параметров у нее не будет, поэтому таблица Параметры пустая. По умолчанию установлен флаг "Вызов Rust метода". В случае установки этого флага буде создан весь необходимый код для взаимодействия с Rust:

- Будут созданы заголовочные файлы  с описанием сигнатур функций на Rust;

- Будет создание код на С++ который вызывает метод Rust;

- Реализовано освобождение памяти после того, как С++ код прочитает значение, которое вернут Rust (общение между С++ и Rust происходит через указатели, поэтому нужно освобождать память);

- На стороне Rust будут так же созданы соответствующие методы.

Так как добавляется функция, автоматически установлен флаг "Возвращает значение".

И нажму "Save".

 

Настройки готовы, теперь можно сгенерировать код.

Для этого на закладке "Сборка" нажму кнопку "Собрать".

 

 

После чего в каталоге, где расположена программа, будет создан каталог с исходным кодом компоненты "new component".

Этот каталог содержит код на С++ и Rust

 

 

Теперь нужно собрать внешнюю компоненту. Так как библиотека на Rust статическая и включается в динамическую библиотеку (внешняя компонента это технически динамическая библиотека), то сначала нужно создать библиотеку на Rust, а потом на C++.

Для этого нужно подготовить среду для сборки.

Для Rust, нужно скачать и установить приложение-установщик со страницы https://www.rust-lang.org/ru/tools/install.

Для C++ нужно скачать и установить visual studio со страницы https://visualstudio.microsoft.com/vs/community/.

Для разработки на Rust я использую две IDE, VSCode и RustRover.

Открою каждую папку в своей IDE (С++ в visual studio, Rust в RustRover).

Важно! Открывать С++ нужно через CMake файл

 

 

И выбрать файл CMakeLists.txt из папки, которая была создана при нажатии на "Собрать"

 

 

В проекте на С++ для каждой добавленной в конструкторе функции будет создан одноименный файл *.cpp

 

 

Который вызывает метод на Rust

 

 

Для моей текущей задачи в коде на С++ ничего менять и добавлять не нужно.

Перейду к кода на Rust. Отрою его в IDE RustRover.

В Rust так же для каждого метода добавленного в конструкторе будет создан одноименный файл.

 

 

Для моей текущей задачи также ничего дорабатывать в коде на Rust не нужно, так как сгенерированный код и так по умолчанию возвращает строку "returder value from rust".

Поэтому просто соберу библиотеку на Rust командой cargo build

 

 

После сборки в каталоге rust появится собранная статическая библиотека (файл с расширением lib)

 

 

Теперь нужно создать динамическую библиотеку (чем является компонента) на стороне С++

Статическая библиотека уже прописана в фале CMakeList.txt, добавлять ее не нужно. Исходные файлы так же автоматически добавятся при генерации кода  конструктором.

 

 

После сборки в каталоге cpp также появится собранная библиотека, уже динамическая (файл с расширением dll)

 

 

Все готово! Можно использовать компоненту в 1С.

В созданном каталоге также есть шаблон обработки для тестирования компоненты. 

 

 

Добавлю в конфигураторе вызов моего метода

 

 

И запущу в режиме предприятия.

 

 

При запуске вывелась строка, которую возвращает метод Rust.

Второй пример посложнее. Метод должен получить данные из SQLite и вернуть в виде строки (список пользователей).

Добавлю еще одни метод, назову его ПолучитьПользователей

 

 

И аналогично нажму "Собрать" на закладке "Сборка".

В С++ и Rust, аналогично первому примеру, также добавились файлы для реализации новой функции.

 

 

Для работы с библиотекой SQLite в Rust я буду использовать крейт (так в rust называются библиотеки или пакете, терминологически правильно говорить крейт) rusqlite.

Так как я собирают приложение на rust  в статическую библиотеку, то все ее зависимости также должны быть включены в нее статически, включая библиотеку rusqlite.

Для этого в файле cargo.tolm в секции "Зависимости" укажу

 

 

bundle означает, что rusqlite будет включена в мою библиотеку статически.

Полный код на rust для файла impl_GetUsers.rs, который реализует метод ПолучитьПользователей(), будет такой.

 

 

Функция getUsers выполняет запрос и возвращает пользователей в виде вектора строк (вектор в rust это аналог динамического массива).

Функция main через метод join объединяет элементы вектора в строку и возвращает функции на C++, которая уже вернет его функции на встроенном языке.

Также как и в прошлом примере, соберу сначала библиотеку на Rust , а потом на С++ (полностью аналогично первому примеру).

Добавлю метод в обработку.

 

 

И выполню в режиме предприятия.

 

 

Конструктор распространяется бесплатно.

Ссылка на github

Готовые сборки (из раздела релизы) 

См. также

Разработка внешних компонент POS терминал Рабочее место Розничная торговля Программист Пользователь Платформа 1С v8.3 1С:Комплексная автоматизация 1.х 1С:Управление торговлей 10 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Розничная и сетевая торговля (FMCG) Рестораны, кафе и фаст-фуд Реклама, PR и маркетинг Управленческий учет Платные (руб)

Медиадисплей покупателя может отображать текущую покупку на кассовом месте, показывать видеорекламу, баннеры, во время простоя разворачивать рекламу на весь экран. Экран можно использовать в качестве графического меню-борда в кафе и видеовывески. В качестве устройства отображения можно использовать Android-планшеты, смарт-телевизоры с Android, мониторы или проекторы под управлением Windows или Linux-компьютера. Linux-версия успешно запускается на одноплатных компьютерах Raspberri Pi и Orange Pi. Настраивается ЛЮБОЙ ДИЗАЙН экрана при помощи встроенного графического редактора! Решение можно масштабировать от одного экрана до тысяч экранов с централизованным управлением.

18000 руб.

30.05.2017    53843    9    69    

46

Разработка внешних компонент Телефония, SIP Программист Платформа 1С v8.3 Конфигурации 1cv8 Россия Платные (руб)

Внешняя компонента выполнена по технологии Native API для 1С 8.х, обеспечивает доступ к программным АТС Asterisk (FreePBX, Elastix) через AMI интерфейс. Через него можно управлять многими функциями Asterisk (определение номеров, перевод звонков, набор телефона и т. д.)

2400 руб.

04.05.2018    47016    123    66    

67

Разработка внешних компонент Программист Платформа 1С v8.3 Платформа 1C v8.2 Платные (руб)

Внешняя компонента, позволяющая посылать команды и получать ответы по GraphQL протоколу из 1С.Может быть использована при интеграции. В 1С работает на стороне "клиента".

4600 руб.

27.06.2023    3495    3    0    

4

Разработка внешних компонент Программист Платформа 1С v8.3 Конфигурации 1cv8 1С:Управление нашей фирмой 1.6 1С:Бухгалтерия 3.0 Платные (руб)

Внешняя компонента позволяет работать c TWAIN-совместимым оборудованием (сканерами, камерами) . Полностью совместима со стандартной TWAIN-компонентой из БСП и может применяться как ее замена без изменения вызовов, при этом может работать с 64-разрядной платформой, а так же имеет расширенную функциональность, например, сохранение результата непосредственно в PDF без использования сторонних утилит. Прекрасно работает на сервере, тонком клиенте и веб-клиенте (проверена работа в браузерах Google Chrome, Mozilla Firefox и Microsoft Internet Explorer).

3000 руб.

12.05.2020    28455    138    100    

91

Разработка внешних компонент Программист Платформа 1С v8.3 Конфигурации 1cv8 1С:Управление торговлей 11 Платные (руб)

Внешняя компонента для конвертации PDF файлов в картинки без использования дополнительных программ. Работает на сервере и в тонком клиенте.

2400 руб.

25.06.2024    1011    2    4    

2

Разработка внешних компонент Программист Платформа 1С v8.3 Конфигурации 1cv8 Платные (руб)

Внешняя компонента в виде библиотеки (.dll файл), позволяющая посылать команды и получать ответы по протоколу WebSocket из 1С. Компонента работает только на стороне "клиента".

4440 руб.

22.06.2020    18280    18    33    

22

Разработка внешних компонент Программист Платформа 1С v8.3 Конфигурации 1cv8 Платные (руб)

Позволяет автоматизировать работу с картинками. С помощью компоненты можно измерять размер изображений, поворачивать их, наносить водяные знаки, конвертировать из одного формата в другой. Будет очень полезна для интернет-магазинов и всех, кому постоянно требуется работать с различными графическими форматами. Выполнена по технологии NativeAPI. Работает с форматами: jpg (jpeg), png, bmp, gif, tif

3600 руб.

02.09.2010    77380    72    257    

191
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. SerVer1C 823 04.12.24 14:13 Сейчас в теме
Знающие люди, проясните, почему нет шаблонов внешней компоненты, например, на языке go, ведь на нём было бы гораздо удобнее и проще писать компоненты.
2. kovalevdmv 71 04.12.24 14:47 Сейчас в теме
(1) Можно сделать статическую библиотеку на GO, подключить ее к C++ компоненте и вызывать методы, точно так же как в моем примере, только у меня С++ -> FII -> Rust а будет С++ -> FII -> Go. Совсем без С++ вряд ли получится обойтись, потому что платформа написана на С++ и API внешней компоненты (если говорить о native API ) подразумевает выделение и освобождение памяти через менеджер памяти который платформа передает внешней компоненте (по спецификации native API). И если учесть что все равно (из самого простого варианта) придется использовать обертку из С++ и так же усложнять код на GO (отключать местами сборщик мусора, чтобы он не уничтожил данные которые еще используются в С++ или в платформе), то удобства не очень много. И к тому же GO больше подходит для сетевых сервисов.Но теоретически можно расширить мой конструктор, чтобы он создавал автоматически шаблон для GO и автоматизировал все неудобство что я описал (отключать GС и освобождать память после использования вручную). Тогда будет удобно. Но пять же GO не под все задачи хорошо подходит.
3. lmnlmn 69 04.12.24 16:42 Сейчас в теме
(1) Go не совместим по ABI с 1С и, как отметили выше, геморрой с Cgo не стоит свеч. А таки, да, приятный язык.
4. scipion13 7 04.12.24 17:31 Сейчас в теме
А почему не писать внешние компоненты сразу на Rust, без использования C++? Например, при помощи https://infostart.ru/1c/articles/1920565/
Или были замечены какие-то проблемы с этим?
5. kovalevdmv 71 04.12.24 17:43 Сейчас в теме
(4) Сложнее будет разобраться, если процесс платформы будет падать. Платформа же - черный ящик. Разработчики не всегда отвечают. Даже если у вас есть возможность официально с ними общаться, они не будут помогать с проблемами на чистой rust компоненте. Механизм внешних компонент даже с С++ native API не всегда идеально работает. Поэтому мне лично так проще. API на С++ это официальная методика от 1С, больше вероятности разобраться, если что-то пойдет не так. С rust С++ тоже взаимодействует по простому FFI интерфейсу, там тоже проблем и сложностей не должно быть.
tsmult; scipion13; +2 Ответить
9. I_G_O_R 69 04.12.24 20:51 Сейчас в теме
(5)
Сложнее будет разобраться, если процесс платформы будет падать.

Я себе сделал тест https://github.com/medigor/addin1c/blob/main/example-test/src/main.rs, просто запускаешь под valgrind и проверяешь если надо, а проверять надо только когда меняешь библиотеку для разработки компонент, сами компоненты уже просто на 1С проверяешь, дебажить можно на файловой базе, но в основном это не требуется.
scipion13; +1 Ответить
6. kovalevdmv 71 04.12.24 18:19 Сейчас в теме
(4) А мой подход я уже опробовал на компонентах для rabbitMQ и kafka, под wn и linux работает. С памятью паблем нет, утечек нет (выделение, освобождение памяти в куче уже на стороне платформы, когда компоннета выделяет память через аллокатор переданный платформой, а уже платформа сама освобождает, когда данные ей не нужны). И время дополнительно не нужно тратить на доп. технические вопросы.
nkolentcev; JohnyDeath; scipion13; +3 Ответить
7. scipion13 7 04.12.24 18:33 Сейчас в теме
(6) Я тоже пока не нашел проблем с компонентами написанными на чистом Rust. Использую несколько штук - полет нормальный. Интересуюсь просто может сталкивались с неполадками какими-нибудь и стоит забить тревогу.
В любом случае статья и продукт - отличные! Если компоненты на Rust будут сбоить - обязательно воспользуюсь вашим решением. Tauri раньше смотрел мельком, а оно вон как симпатично получается. Для своих задач остановил свой выбор на Slint для GUI под Rust.
Низкий поклон и спасибо за труд :).
nkolentcev; kovalevdmv; +2 Ответить
8. I_G_O_R 69 04.12.24 20:46 Сейчас в теме
Можно было с++ под ковер замести и собирать всю компоненту с помощью cargo,

типа вот так:
пишешь функцию на с++:
https://github.com/medigor/addin1c/blob/main/addin1c-test/src/memory_manager.cpp#L22

вызываешь её из Rust:
https://github.com/medigor/addin1c/blob/main/addin1c-test/src/memory_manager.rs#L20

сборка с++:
https://github.com/medigor/addin1c/blob/main/addin1c-test/build.rs
kovalevdmv; +1 Ответить
10. kovalevdmv 71 04.12.24 22:06 Сейчас в теме
(8) Не было цели вообще С++ не использовать. В конструкторе когда метод добавляешь, есть флаг "Вызов rust метода", если он установлен, то сгенерируется код вызова rust и сам метод и код на rust, если не установлен, подразумевается что хотят только С++ метод использовать. Опционально. И только С++ можно и вызов метода из rust. И вообще без rust на чистом С++ и в смешанном режиме.
11. Feelthis 38 04.12.24 23:17 Сейчас в теме
Когда платформа что-то не умеет (например общаться с rabbit mq) я писал сервис на другом языке например nodejs или python и оборачивал в http сервис. Общение платформы и http сервиса посредством http запросов. Не думаю что мой вариант работает медленнее чем внешняя компонента, зато разработка сильно проще и отладка. Что думаете? (Понятно что не для всех случаев подходит)
scipion13; +1 Ответить
12. kovalevdmv 71 05.12.24 00:14 Сейчас в теме
(11) тоже хороший вариант если подходит для решения задачи. Я тоже делал сервисы на питоне и связь по rest api. ВК нужны для определённого класса задач.
13. acces969 362 05.12.24 11:06 Сейчас в теме
Отлично! Спасибо большое. Как раз планировал скоро заняться созданием компоненты. Скажите, подключить библиотеку tesseract к компоненте для 1С не составит труда с помощью вашего инструмента?
14. kovalevdmv 71 05.12.24 12:12 Сейчас в теме
(13)
подключить библиотеку tesseract

Имеете ввиду крейт для раста для работы с tesseract для распознования текста?
Теоретически любой крейт раста должен работать, только возможно нужно указывать чтобы бы статически включался в библиотеку, как в статье с крейтом для sqlite.
Ну или для С++ тоже есть библиотека.
Я бы для раста попробовал сначала.
acces969; +1 Ответить
15. acces969 362 05.12.24 12:25 Сейчас в теме
(14) Я с растом не работал, даже синтаксис не представляю какой. Точно ли будет легче человеку, не знающего ли раста, ни с++, начать с раста?
16. kovalevdmv 71 05.12.24 12:47 Сейчас в теме
(15) Возможно тогда проще реализовать внешний сервис н.п. на питоне и через rest api общаться. Я вот так делал видео
Внешняя компонента это не единственный способ расширить возможность платформы. И не самый простой. ВК удобно для взаимодействия с устройствами или что-то подобное. Или если что-то совсем мелкое и не хочется отдельный сервис поднимать. Но если допустимо решить через внешний сервис и нет знаний с++ или rust, то думаю только ради одной задачи не особенно целесообразно тратить время на изучение, если конечно не было отдельной цели изучить rust или c++.
acces969; +1 Ответить
17. acces969 362 05.12.24 13:09 Сейчас в теме
(16) Цель - освоить именно создание внешней компоненты на с++. Последняя ачивка в 1С, так сказать. Тем более, распознавание текста в 1с, в одной внешней обработке без saas - полезная вещь. Я ее сделаю, давно хочу. И ваша статья очень мне в этом поможет, так что спасибо вам большое.
Только наличие языка rust не входило в планы, вот и думаю - что за зверь такой. Если с ООП я работал уже там и сям, то мультипарадигменный язык - даже не представляю что это такое.
18. kovalevdmv 71 05.12.24 13:36 Сейчас в теме
(17) Тогда лучше с rust сразу. У него оч удобный пакетный менеджер, удобно ставить пакеты. Архитектура языка не позволит написать код с утечкой памяти или получить висячий указатель (использоват освобожденную память) (если конечно не использовать unsafe блоки). Нет переусложнений из-за ООП. Там только структуры и методы с ними ассоциированные. Наследование через композицию, тоже все упрощает. Современный С++ тоже позволяет писать без указателей и ручного выделения/осбобождения, использовать умные указатели, будет как система владения в rust, но при этом нет ни какого запрета использовать любой другой подход в стиле си и получить кучу проблем с памятью (если не писать очень внимательно или использовать утилиты для отлеживания утечек). А rust это в принцепе не пропустит (если явно не указать что мы пишем unsafe код)
acces969; +1 Ответить
19. dsdred 3647 05.12.24 14:05 Сейчас в теме
Спасибо за статью и разработку.
Хотел Rust пощупать, да руки не доходили, теперь есть с чем побаловаться ;)
20. grumagargler 726 06.12.24 01:03 Сейчас в теме
В качестве ненормального, но любопытного опыта (базовое условие - знание с++):
- пишем свою современную обёртку для возможности почти также легко добавлять свои функции в компоненту, как в общий модуль
- пишем свой конвертер коллекций, или просто на первых порах, json-обёртки
- налаживаем автоматическую сборку под все нужные ОС и разрядности
- выворачивам из 1с наружу сервис для получения данных из 1с, если нужно

Это всё конечно конкретный головняк, и типовую конфигурацию так писать не стоит, но есть и плюсы:
- тестируемость
- производительность
- надёжность, если что-то ломается, то виноваты сами, а значит починить можем сами, без v8@1c.ru
- скорость разработки, за счёт нескольких вещей:
- возможности (с умом) применять все парадигмы
- крутые инструменты разработки (заряжаем neovim + всё что для c++ и cmake нужно, copilot и погнали)
- отладка и перезапуск, занимает секунды
- больший охват разработчиков (не обязательны знания 1с)

Конечно, закрытие месяца на с++ не напишешь, но всякие там сервисы, шуструю работу с коллекциями, работу с изображениями, семантический поиск, анализ данных и прочее, очень даже ;-)
21. starik-2005 3092 06.12.24 14:26 Сейчас в теме
(20)
закрытие месяца на с++ не напишешь
Было бы желание )))
В действительности, закрытие месяца - это распределение множества сумм по некоторому количеству "баз", иногда и рекурсивненько по дереву переделов с контролем зацикленности. Вот не вижу тут ничего сложного для С[++|#|...].
22. nkolentcev 06.12.24 15:10 Сейчас в теме
(20) челлендж на год ... напиши свою ERP на rust/tauri или go+flutter ))
23. starik-2005 3092 06.12.24 15:53 Сейчас в теме
(22)
напиши свою ERP на
Проблемы ЕРП в том, что они нифига не работают "искаропки", их постоянно допиливают. И если на 1С допил коробок можно наладить с не сильно большим количеством напряга, то на чем-то остальном эти допилы уже совершенно иного уровня расходов потребуют.

Если вот взять и под конкретного бизнес-пользователя писать, то тут не сильно много разницы, на чем это все пилить. И если ты у него в штате и никуда не свалишь, то на чем-то помимо 1С, если ты этим хорошо владеешь, вполне себе сделаешь, а может и быстрее получится. Но бизнес-пользователь совсем не уверен, что ты никуда не денешься, и для него важен вопрос о том, кто это все будет доделывать. А для другого бизнес-пользователя твоя поделка будет всего-лишь тем, что можно показать в качестве прототипа, ибо у него есть свои хотелки и свое понимание, как этот мир устроен. Ну может быть кто-то трех бизнес-пользователей потянет со скрипом и бессонными ночами, может кто-то сможет создать и удержать команду, но это проект на пусть 10 компаний. Берешь 11-ю - все, нужно еще штат раздувать. В 1С и ее франчах штат тянет несколько тысяч компаний, а ларьки - ну им и других коробок хватает без ЕРП.
24. nkolentcev 06.12.24 17:38 Сейчас в теме
(23) в каждой шутке есть доля шутки ... go прост в изучении, высокопроизводительные и ресурсоемкие задачи конечно требуют более глубокого погружения, а с 1с разве не так? Стоит только выйти за рамки корпоративных внедрений и толковых разрабов не отыщешь.
25. bayselonarrend 2138 06.12.24 20:38 Сейчас в теме
Не ну это восторг, спасибо)
26. artly2000 2 10.12.24 09:33 Сейчас в теме
Оставьте свое сообщение