# example-native-api-rs Пример внешней компоненты для **1С:Предприятие 8** по технологии **Native API** на языке **Rust** [Документция на ИТС](https://its.1c.ru/db/metod8dev#content:3221:hdoc) | [Шаблон компоненты на C++ от Infactum](https://github.com/Infactum/addin-template) ## Преимущества по сравнению с компонентой на C++ * Преимущества самого языка *Rust* и его экосистемы (более современный и безопасный язык, удобный пакетный менеджер) * Для Windows не требуется msvc (напомню, что организации должны иметь лицензию) * Собирается полностью с использованием свободных инструментов * На linux можно собирать для windows, соответственно удобно использовать в CI контейнеры linux ## Обзор Компоненты по технологии *Native API* предполагают разработку на языке *C++*, т.к. компонента должна принимать и возвращать указатели на виртуальные классы *C++*. Компонента для windows должна собираться только компилятором msvc, а для linux и macos подойдет gcc/clang. Как известно, взаимодействие *Rust* с *C++* из коробки не поддерживается. Одним из вариантов было использовать [cxx](https://github.com/dtolnay/cxx) или подобные библиотеки. Это также бы потребовало использовать msvc. Другой вариант - вручную реализовать виртуальные таблицы, именно этот вариант и реализован. На [godbolt](https://godbolt.org/z/KM3jaWMWs) можно посмотреть, как выглядят виртуальные таблицы для разных компиляторов. Виртуальные таблицы *msvc* отличаются от *gcc*/*clang*, при этом *gcc* и *clang* используют одинаковое ABI. Виртуальные таблицы реализованы в объеме достаточном для создания компоненты. Также, для тестирования с помощью [valgrind](https://valgrind.org/) и подобных утилит, разработана [библиотека тестирования](https://crates.io/crates/addin1c-test), выполненные тесты позволяют убедиться в надежности технологии. ## Описание файлов ### пример компоненты: * [lib.rs](src/lib.rs) - корень крейта, здесь располагаются экспортные функции GetClassNames и др. * [addin1.rs](src/addin1.rs) - реализация компоненты с помощью низкоуровнего интерфейса, причем весь код безопасный. * [addin2.rs](src/addin2.rs) - упрощенный вариант, используется другой трейт. ### [conf1c](conf1c) - конфигурация 1С (выгрузка из конфигуратора 8.3.22), минимальный тестовый код. * [DataProcessors/Обработка1/Forms/Форма/Ext/Form/Module.bsl](conf1c/DataProcessors/Обработка1/Forms/Форма/Ext/Form/Module.bsl) - тесты для ручного запуска. ## Разработка Я использую для разработки VS Code. Отлаживать и тестировать компоненту удобнее всего в файловой базе. Чтобы при нажатии F5 сразу запускалась 1С, нужно поместить в файл *.vscode/launch.json* примерно такой код: ```json { "version": "0.2.0", "configurations": [ { "type": "lldb", "request": "launch", "name": "Debug 1С", "program": "путь/к/файлу/1cv8c", "args": [ "/IBName", "Test1" ], "cwd": "${workspaceFolder}", "preLaunchTask": "rust: cargo build" } ] } ``` Первоначально возможно нужно использовать параметр: ```json "preLaunchTask": "${defaultBuildTask}" ``` Для разработки на linux я использую виртуальную машину Hyper-V, VS Code подключается по ssh. Чтобы запуск 1С работал из ssh, нужно в конфигурацию запуска добавить: ```json "env": {"DISPLAY": ":1"} ``` Для разработки и тестирования также подходит [Учебная версия 1С](https://online.1c.ru/catalog/free/learning.php), но версия для windows только x32. ## Поддержка платформ Компоненты дополнительно протестированы с помощью [valgrind](https://valgrind.org/) на `linux` и [drmemory](https://drmemory.org/) на `windows`. - Windows x64 - протестировано, работает и gnu и msvc. - Windows x32 - протестировано, работает и gnu и msvc. - Linux x64 - протестировано, работает. - Linux x32 - не тестировал, думаю что должно работать, но платформа устарела. - MacOS - не тестировал, думаю должно работать, т.к. работает Linux x64. - Android/iOS/веб-клиент - не тестировал, не реализовано и планов таких нет. ## Сборка без установки Rust в контейнере Собрать можно в контейнере с помощью скриптов: [build-with-docker-linux](build-with-docker-linux) и [build-with-docker-windows](build-with-docker-windows), требуется установленный `podman` или `docker`. Скрипты не предназначены для CI, а необходимы лишь для одноразовой сборки, чтобы пощупать технологию. ## Замечания по разработке внешних компонент - Самый легкий способ разработать компоненту - вместо нее сделать микросервис с http api. Используйте этот способ в первую очередь. - Если вдруг полностью нативный способ (предложенный в этом проекте) не работает, то можно разработать на rust статическую библиотеку(crate-type = "staticlib") и использовать её в проекте c++. - Для веб-клиента можно попробовать использовать wasm в ПолеHtmlДокумента, см. https://developer.mozilla.org/en-US/docs/WebAssembly/Rust_to_wasm. Из плюсов - не требуется установка внешних компонент, из минусов - ПолеHtmlДокумента должно быть выведено на форму, сама форма должна быть открыта. ## Альтернативы - https://github.com/tuplecats/rust-native-1c - https://github.com/Sebekerga/native_api_1c