1
0
mirror of https://github.com/medigor/example-native-api-rs.git synced 2025-07-15 01:34:31 +02:00

project reorganization

This commit is contained in:
medigor
2023-12-14 01:05:05 +03:00
parent 9fad5a392d
commit 071596b2fc
11 changed files with 53 additions and 39 deletions

View File

@ -1,18 +1,9 @@
[package]
name = "addin"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib"]
[workspace]
members = ["addin1c", "example"]
resolver = "2"
[profile.release]
# opt-level = "z" # Optimize for size.
lto = true # Enable Link Time Optimization
codegen-units = 1 # Reduce number of codegen units to increase optimizations.
panic = "abort" # Abort on panic
strip = true # Automatically strip symbols from the binary.
[dependencies]
utf16_lit = "2.0"
smallvec = "1.11"

View File

@ -20,13 +20,19 @@
На [godbolt](https://godbolt.org/z/KM3jaWMWs) можно посмотреть, как выглядят виртуальные таблицы для разных компиляторов. Виртуальные таблицы *msvc* отличаются от *gcc*/*clang*, при этом *gcc* и *clang* используют одинаковое ABI. Виртуальные таблицы реализованы в объеме достаточном для создания компоненты.
## Описание файлов
* [src/lib.rs](src/lib.rs) - корень крейта, здесь располагаются экспортные функции GetClassNames и др.
* [src/ffi.rs](src/ffi.rs) - в этом модуле всё что связано с взаимодействием, также здесь находится весь небезопасный код.
* [src/addin1.rs](src/addin1.rs) - здесь непосредственно реализация компоненты, причем весь код безопасный.
* [src/addin2.rs](src/addin2.rs) - упрощенный вариант, используется другой трейт.
* [src/simple.rs](src/simple.rs) - трейт Addin для упрощенного варианта.
* [src/macros.rs](src/macros.rs) - содержит единственный макрос `name!` для удобного задания имен свойств, методов, классов.
* [conf1c](conf1c) - конфигурация 1С (выгрузка из конфигуратора 8.3.22), минимальный тестовый код.
### [addin1c](addin1c) - крейт с вспомогательными объектами
* [lib.rs](addin1c\src\lib.rs) - корень крейта.
* [ffi.rs](addin1c\src\ffi.rs) - в этом модуле всё что связано с взаимодействием, также здесь находится весь небезопасный код.
* [simple.rs](addin1c\src\simple.rs) - трейт Addin для упрощенного варианта.
* [macros.rs](addin1c\src\macros.rs) - содержит единственный макрос `name!` для удобного задания имен свойств, методов, классов.
### [example](example) - пример компоненты, содержит 2 объекта:
* [lib.rs](example\src\lib.rs) - корень крейта, здесь располагаются экспортные функции GetClassNames и др.
* [addin1.rs](example\src\addin1.rs) - реализация компоненты с помощью низкоуровнего интерфейса, причем весь код безопасный.
* [addin2.rs](example\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* примерно такой код:

8
addin1c/Cargo.toml Normal file
View File

@ -0,0 +1,8 @@
[package]
name = "addin1c"
version = "0.1.0"
edition = "2021"
[dependencies]
smallvec = "1.11"
utf16_lit = "2.0"

10
addin1c/src/lib.rs Normal file
View File

@ -0,0 +1,10 @@
mod ffi;
mod macros;
mod simple;
pub use ffi::{
create_component, destroy_component, Addin as RawAddin, AttachType, Connection, ParamValue, Tm,
Variant,
};
pub use simple::{Addin as SimpleAddin, MethodInfo, Methods, PropInfo};
pub use utf16_lit::utf16_null;

View File

@ -2,6 +2,6 @@
#[macro_export]
macro_rules! name {
($text:expr) => {
&utf16_lit::utf16_null!($text)
&addin1c::utf16_null!($text)
};
}

10
example/Cargo.toml Normal file
View File

@ -0,0 +1,10 @@
[package]
name = "addin"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib"]
[dependencies]
addin1c = { path = "../addin1c" }

View File

@ -1,9 +1,4 @@
use utf16_lit::utf16;
use crate::{
ffi::{Addin, ParamValue, Tm, Variant},
name,
};
use addin1c::{name, ParamValue, RawAddin, Tm, Variant};
const PROPS: &[&[u16]] = &[
name!("Test"),
@ -45,7 +40,7 @@ impl Drop for Addin1 {
fn drop(&mut self) {}
}
impl Addin for Addin1 {
impl RawAddin for Addin1 {
fn register_extension_as(&mut self) -> &'static [u16] {
name!("Class1")
}
@ -217,7 +212,8 @@ impl Addin for Addin1 {
match param.get() {
ParamValue::Empty => {
if i == 0 {
if !param.set_str(&utf16!("Return value")) {
let s = "Return value".encode_utf16().collect::<Vec<u16>>();
if !param.set_str(&s) {
return false;
}
} else {

View File

@ -1,7 +1,4 @@
use crate::{
simple::{Addin, MethodInfo, Methods, PropInfo},
ffi::{ParamValue, Variant}, name,
};
use addin1c::{name, MethodInfo, Methods, ParamValue, PropInfo, SimpleAddin, Variant};
pub struct Addin2 {
prop1: i32,
@ -52,7 +49,7 @@ impl Addin2 {
}
}
impl Addin for Addin2 {
impl SimpleAddin for Addin2 {
fn name() -> &'static [u16] {
name!("Class2")
}

View File

@ -1,8 +1,5 @@
mod addin1;
mod addin2;
mod simple;
mod ffi;
mod macros;
use std::{
ffi::{c_int, c_long, c_void},
@ -11,8 +8,7 @@ use std::{
use addin1::Addin1;
use addin2::Addin2;
use ffi::{create_component, destroy_component, AttachType};
use utf16_lit::utf16_null;
use addin1c::{create_component, destroy_component, name, AttachType};
pub static mut PLATFORM_CAPABILITIES: AtomicI32 = AtomicI32::new(-1);
@ -42,7 +38,7 @@ pub unsafe extern "C" fn DestroyObject(component: *mut *mut c_void) -> c_long {
#[no_mangle]
pub extern "C" fn GetClassNames() -> *const u16 {
// small strings for performance
utf16_null!("1|2").as_ptr()
name!("1|2").as_ptr()
}
#[allow(non_snake_case)]