Более наглядно представлено в примере.
# Cargo.toml [package] name = "..." version = "0.1.0" edition = "2021" [lib] crate-type = ["cdylib"] [dependencies] native-1c = { git = "https://github.com/tuplecats/rust-native-1c.git" }
Для любой компоненты необходимо реализовать extern функции, которые использует 1С для подключения компоненты:
unsafe extern "C" fn GetClassObject(_name: *const u16, component: *mut *const u8) -> std::os::raw::c_long; unsafe extern "C" fn DestroyObject(_component: *mut *const u8) -> std::os::raw::c_long; unsafe extern "C" fn GetClassNames() -> *const u16; unsafe extern "C" fn SetPlatformCapabilities(capabilities: AppCapabilities) -> AppCapabilities;
Любая структура, которая будет использоваться 1С, должна использовать процедурный макрос native_object
, использовать #[repr(C)]
и реализовывать трейт IComponentBase
:
pub trait IComponentBase { // IInitDoneBaseVTable fn init(&mut self) -> bool; fn get_info(&self) -> i32; fn done(&mut self); // ILanguageExtenderBaseVTable fn get_n_props(&self) -> i32; fn find_prop(&self, prop_name: &str) -> i32; fn get_prop_name(&self, prop_num: i32, prop_alias: i32) -> &str; fn get_prop_val(&self, prop_num: i32, var_prop_val: &mut Variant) -> bool; fn set_prop_val(&mut self, prop_num: i32, var_prop_val: &Variant) -> bool; fn is_prop_readable(&self, prop_num: i32) -> bool; fn is_prop_writeable(&self, prop_num: i32) -> bool; fn get_n_methods(&self) -> i32; fn find_method(&self, method_name: &str) -> i32; fn get_method_name(&self, method_num: i32, method_alias: i32) -> &str; fn get_n_params(&self, method_num: i32) -> i32; fn get_param_def_value(&self, method_num: i32, param_num: i32, var_param_def_value: &mut Variant) -> bool; fn has_ret_val(&self, method_num: i32) -> bool; fn call_as_proc(&mut self, method_num: i32, params: Option<&mut [Variant]>) -> bool; fn call_as_func(&mut self, method_num: i32, ret_vals: &mut Variant, params: Option<&mut [Variant]>) -> bool; // LocaleBaseVTable fn set_locale(&mut self, loc: &str); }