### Loading and Interacting with 1C External Components Source: https://context7.com/medigor/addin1c/llms.txt Demonstrates the process of loading an external component in 1C:Enterprise, instantiating the component object, and performing operations such as property access, method invocation, and handling various data types like dates and binary blobs. ```bsl // Подключение внешней компоненты Если Не ПодключитьВнешнююКомпоненту( ИмяФайлаКомпоненты, "MyAddin", ТипВнешнейКомпоненты.Native, ТипПодключенияВнешнейКомпоненты.НеИзолированно) Тогда Сообщить("Не удалось подключить внешнюю компоненту"); Возврат; КонецЕсли; // Создание объекта компоненты ОбъектКомпоненты = Новый("AddIn.MyAddin.Calculator"); // Работа со свойствами ОбъектКомпоненты.Result = 100; Сообщить(СтрШаблон("Результат: %1", ОбъектКомпоненты.Result)); // Вызов методов Сумма = ОбъектКомпоненты.Add(10, 20); Сообщить(СтрШаблон("10 + 20 = %1", Сумма)); Произведение = ОбъектКомпоненты.Multiply(5); Сообщить(СтрШаблон("Результат * 5 = %1", Произведение)); // Работа с разными типами данных ОбъектКомпоненты.PropI32 = 123; ОбъектКомпоненты.PropF64 = 456.789; ОбъектКомпоненты.PropBool = Истина; ОбъектКомпоненты.PropDate = ТекущаяДатаСеанса(); ОбъектКомпоненты.PropStr = "Строка на русском"; // Работа с двоичными данными Blob = ПолучитьДвоичныеДанныеИзСтроки("Данные"); ОбъектКомпоненты.PropBlob = Blob; // Обработка ошибок Попытка ОбъектКомпоненты.Method1("некорректный параметр"); Исключение Сообщить(СтрШаблон("Ошибка: %1", ОбъектКомпоненты.LastError)); КонецПопытки; ``` -------------------------------- ### Implementing SimpleAddin for 1C Components Source: https://context7.com/medigor/addin1c/llms.txt Demonstrates how to define a 1C external component using the SimpleAddin trait. It includes property getters/setters and method definitions with automatic error handling. ```rust use std::error::Error; use addin1c::{name, AddinResult, CStr1C, Connection, MethodInfo, Methods, PropInfo, SimpleAddin, Variant}; pub struct Calculator { result: i32, last_error: Option> } impl SimpleAddin for Calculator { fn name() -> &'static CStr1C { name!("Calculator") } fn save_error(&mut self, err: Option>) { self.last_error = err; } fn properties() -> &'static [PropInfo] { &[PropInfo { name: name!("Result"), getter: Some(Self::get_result), setter: Some(Self::set_result) }] } fn methods() -> &'static [MethodInfo] { &[MethodInfo { name: name!("Add"), method: Methods::Method2(Self::add) }] } } ``` -------------------------------- ### Manage 1C Platform Events with Connection Source: https://context7.com/medigor/addin1c/llms.txt Demonstrates how to use the Connection interface to set event buffer depth, send synchronous external events, and dispatch asynchronous events from background threads. It requires the addin1c crate and implements the SimpleAddin trait. ```rust use std::{thread, time::Duration}; use addin1c::{cstr1c, CString1C, Connection, SimpleAddin, AddinResult, Variant}; pub struct EventSender { interface: Option<&'static Connection>, } impl EventSender { pub fn new() -> Self { EventSender { interface: None } } fn send_event(&mut self, ret: &mut Variant) -> AddinResult { if let Some(conn) = self.interface { let old_depth = conn.get_event_buffer_depth(); conn.set_event_buffer_depth(100); let result = conn.external_event( cstr1c!("MyAddin"), cstr1c!("DataReady"), cstr1c!("some_data"), ); ret.set_str1c(format!("Отправлено: {}", result))?; thread::spawn(move || { for i in 0..5 { thread::sleep(Duration::from_millis(500)); conn.external_event( cstr1c!("MyAddin"), CString1C::new(&format!("Event{}", i)), CString1C::new(&format!("Data{}", i)), ); } }); } else { ret.set_str1c("Интерфейс недоступен")?; } Ok(()) } fn clear_events(&mut self, _ret: &mut Variant) -> AddinResult { if let Some(conn) = self.interface { conn.clean_event_buffer(); } Ok(()) } } impl SimpleAddin for EventSender { fn name() -> &'static addin1c::CStr1C { addin1c::name!("EventSender") } fn init(&mut self, interface: &'static Connection) -> bool { self.interface = Some(interface); true } } ``` -------------------------------- ### Test 1C External Components Source: https://context7.com/medigor/addin1c/llms.txt Demonstrates how to use the addin1c-test library to instantiate and interact with a compiled component. This allows for unit testing properties and methods without requiring the full 1C Enterprise environment. ```rust use std::error::Error; use addin1c_test::{name, str1c, TestAddinLib, Variant}; fn main() -> Result<(), Box> { let lib = TestAddinLib::new("./target/release/libaddin.so")?; let object = lib.new_addin("Class1")?; let value = Variant::new_i32(42); object.set_property(name!("PropI32"), &value)?; let result = object.get_property(name!("PropI32"))?; assert_eq!(result.get_i32(), Some(42)); let str_value = "Привет из Rust!".encode_utf16().collect::>(); let value = Variant::new_str(&str_value); object.set_property(name!("PropStr"), &value)?; let result = object.get_property(name!("PropStr"))?; assert_eq!(result.get_str(), Some(str_value.as_slice())); let mut params = [ Variant::new_str(str1c!("Hello")), Variant::new_str(str1c!(" ")), Variant::new_str(str1c!("World")), ]; let result = object.call_as_func(name!("Concat"), &mut params)?; assert_eq!(result.get_str(), Some(str1c!("Hello World").as_slice())); println!("Все тесты пройдены!"); Ok(()) } ``` -------------------------------- ### Configure Cargo.toml for 1C Components Source: https://context7.com/medigor/addin1c/llms.txt Provides the necessary Cargo.toml configuration to build a Rust project as a dynamic library (cdylib) compatible with 1C. Includes optimization settings for production releases. ```toml [package] name = "my-addin" version = "0.1.0" edition = "2021" [lib] crate-type = ["cdylib"] [dependencies] addin1c = { version = "0.7", features = ["chrono"] } chrono = "0.4" [profile.release] lto = true codegen-units = 1 strip = true [dev-dependencies] addin1c-test = "0.2" ``` -------------------------------- ### Testing External Components Source: https://context7.com/medigor/addin1c/llms.txt Using the addin1c-test library to verify component functionality, property access, and method execution without the 1C platform. ```APIDOC ## TestAddinLib API ### Description Provides an interface to load a compiled component and simulate 1C platform calls for testing purposes. ### Methods - **new_addin(name)**: Creates an instance of the component class. - **set_property(name, value)**: Sets a property value on the component. - **get_property(name)**: Retrieves a property value. - **call_as_func(name, params)**: Executes a method on the component. ### Response Example // Returns Result for property access and method calls. ``` -------------------------------- ### Implement 1C Native API Entry Points Source: https://context7.com/medigor/addin1c/llms.txt Defines the required C-compatible functions for a 1C external component, including object creation, destruction, and platform capability registration. These functions allow the 1C platform to interface with the Rust-based component. ```rust use std::ffi::{c_int, c_long, c_void}; use std::sync::atomic::{AtomicI32, Ordering}; use addin1c::{create_component, destroy_component, name, AttachType}; mod my_addin; use my_addin::MyAddin; pub static PLATFORM_CAPABILITIES: AtomicI32 = AtomicI32::new(-1); #[no_mangle] pub unsafe extern "C" fn GetClassObject(name: *const u16, component: *mut *mut c_void) -> c_long { match *name as u8 { b'1' => { let addin = MyAddin::new(); create_component(component, addin) } _ => 0, } } #[no_mangle] pub unsafe extern "C" fn DestroyObject(component: *mut *mut c_void) -> c_long { destroy_component(component) } #[no_mangle] pub extern "C" fn GetClassNames() -> *const u16 { name!("1").as_ptr() } #[no_mangle] pub extern "C" fn SetPlatformCapabilities(capabilities: c_int) -> c_int { PLATFORM_CAPABILITIES.store(capabilities, Ordering::Relaxed); 3 } #[no_mangle] pub extern "C" fn GetAttachType() -> AttachType { AttachType::Any } ``` -------------------------------- ### Handle 1C Dates with Tm and Chrono Source: https://context7.com/medigor/addin1c/llms.txt Shows how to create and manipulate 1C-compatible date structures using the Tm struct. It also demonstrates optional conversion to and from the chrono library types when the 'chrono' feature is enabled. ```rust use addin1c::{Tm, Variant, AddinResult}; #[cfg(feature = "chrono")] use chrono::{Utc, NaiveDate, NaiveDateTime}; fn work_with_dates(output: &mut Variant) -> AddinResult { let tm = Tm { year: 124, mon: 0, mday: 15, hour: 14, min: 30, sec: 0, ..Tm::default() }; output.set_date(tm); Ok(()) } #[cfg(feature = "chrono")] fn work_with_chrono(output: &mut Variant) -> AddinResult { let now = Utc::now(); let tm: Tm = now.into(); output.set_date(tm); let naive = NaiveDate::from_ymd_opt(2024, 6, 15) .unwrap() .and_hms_opt(10, 30, 0) .unwrap(); let tm: Tm = naive.into(); output.set_date(tm); let tm_back: NaiveDateTime = tm.into(); assert_eq!(naive, tm_back); Ok(()) } ``` -------------------------------- ### Handling 1C Data Types with Variant Source: https://context7.com/medigor/addin1c/llms.txt Shows how to safely interact with 1C platform data types including integers, floats, booleans, strings, dates, and binary blobs using the Variant structure. ```rust use addin1c::{Variant, Tm, AddinResult}; fn demonstrate_variants(input: &mut Variant, output: &mut Variant) -> AddinResult { let int_value = input.get_i32()?; output.set_i32(int_value * 2); let str_value = input.get_string()?; output.set_str1c(format!("Result: {}", str_value))?; output.set_empty(); Ok(()) } ``` -------------------------------- ### Native API Entry Points Source: https://context7.com/medigor/addin1c/llms.txt Standard exported functions required for the 1C platform to load and manage the lifecycle of the external component. ```APIDOC ## Native API Entry Points ### Description These functions are exported by the dynamic library to allow the 1C platform to instantiate, identify, and manage the component. ### Methods - **GetClassObject**: Instantiates the component class. - **DestroyObject**: Cleans up component memory. - **GetClassNames**: Returns a pipe-separated list of supported class names. - **SetPlatformCapabilities**: Configures platform-specific capabilities. - **GetAttachType**: Defines the isolation level for the component. ### Request Example // The 1C platform calls these functions automatically upon loading the .dll or .so file. ``` -------------------------------- ### Create UTF-16 strings with the name! macro Source: https://context7.com/medigor/addin1c/llms.txt The name! macro generates static, null-terminated UTF-16 strings required by the 1C Native API for identifying properties, methods, and class names within an external component. ```rust use addin1c::name; const PROPS: &[&CStr1C] = &[ name!("Test"), name!("PropI32"), name!("PropF64"), name!("PropBool"), name!("PropDate"), name!("PropStr"), name!("PropBlob"), ]; const METHODS: &[&CStr1C] = &[ name!("Method1"), name!("Method2"), ]; impl RawAddin for MyAddin { fn register_extension_as(&mut self) -> &'static CStr1C { name!("MyClassName") } } ``` -------------------------------- ### Implement low-level interface with RawAddin trait Source: https://context7.com/medigor/addin1c/llms.txt The RawAddin trait provides a low-level interface for full control over component behavior. It requires manual implementation of property and method lookup, access, and execution logic. ```rust use addin1c::{name, CStr1C, RawAddin, Tm, Variant}; const PROPS: &[&CStr1C] = &[name!("PropI32"), name!("PropStr")]; const METHODS: &[&CStr1C] = &[name!("Concat")]; pub struct MyAddin { prop_i32: i32, prop_str: String, } impl RawAddin for MyAddin { fn register_extension_as(&mut self) -> &'static CStr1C { name!("MyClass") } fn get_prop_val(&mut self, num: usize, val: &mut Variant) -> bool { match num { 0 => { val.set_i32(self.prop_i32); true } 1 => val.set_str1c(self.prop_str.as_str()).is_ok(), _ => false, } } fn call_as_func(&mut self, num: usize, params: &mut [Variant], ret: &mut Variant) -> bool { match num { 0 => { let mut buf = Vec::::new(); for param in params { if let Ok(s) = param.get_str1c() { buf.extend_from_slice(s); } } ret.set_str1c(buf.as_slice()).is_ok() } _ => false, } } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.