Sebekerga / native_api_1c

Crate for simple implementation of Component for Native API 1C:Enterprise written in rust
https://crates.io/crates/native_api_1c
62 stars 13 forks source link

Пустая строка не пустая (null terminator) #5

Closed Toveal closed 10 months ago

Toveal commented 11 months ago

Здравствуйте. Написал простую компоненту в качестве примера. Получаю пустую строку, проверяю в 1С на пустую строку, но она не является пустой строкой

Код Rust:

use std::sync::Arc;

use native_api_1c::{native_api_1c_core::ffi::connection::Connection, native_api_1c_macro::AddIn};

#[derive(AddIn)]
pub struct TestStr {
    #[add_in_con]
    connection: Arc<Option<&'static Connection>>,

    #[add_in_func(name = "GetEmptyString", name_ru = "ПолучитьПустуюСтроку")]
    #[returns(Str)]
    pub get_empty_string: fn(&Self) -> String,
}

impl TestStr {
    pub fn new() -> Self {
        Self {
            connection: Arc::new(None),
            get_empty_string: Self::get_empty_string,
        }
    }

    pub fn get_empty_string(&self) -> String {
        "".to_string()
    }
}

Код 1С:

УстановитьВнешнююКомпоненту("ОбщийМакет.Testik");
ВК = ПодключитьВнешнююКомпоненту("ОбщийМакет.Testik", "Testik", ТипВнешнейКомпоненты.Native);
ВК = Новый("AddIn.Testik.TestStr"); 

ПростоПустаяСтрока = ВК.ПолучитьПустуюСтроку();

Если ПростоПустаяСтрока = "" Тогда
    Сообщить("Пустая строка реально пустая!");
Иначе
    Сообщить("Пустая строка не пустая? Хмм");
КонецЕсли;

Используется библиотека с GitHub. Версия 0.10.5

[dependencies]
native_api_1c = { git = "https://github.com/Sebekerga/native_api_1c" }
Sebekerga commented 11 months ago

Посмотрю попожже, спасибо за репорт

Toveal commented 11 months ago

Значение: image

Заметил одну особенность. Если значение переменной "ПростоПустаяСтрока" поместить в ТекстовыйДокумент (УстановитьТекст) и получить обратно (ПолучитьТекст) то проверка на пустую строку работает

УстановитьВнешнююКомпоненту("ОбщийМакет.FBReader");
ВК = ПодключитьВнешнююКомпоненту("ОбщийМакет.FBReader", "FBReader", ТипВнешнейКомпоненты.Native);
ВК = Новый("AddIn.FBReader.TestStr"); 

ПростоПустаяСтрока = ВК.ПолучитьПустуюСтроку();

Если ПростоПустаяСтрока = "" Тогда
    Сообщить("Пустая строка реально пустая!");
Иначе
    Сообщить("Пустая строка не пустая? Хмм");
КонецЕсли;

ТекстФайл = Новый ТекстовыйДокумент;
ТекстФайл.УстановитьТекст(ПростоПустаяСтрока);

НоваяПустаяСтрока = Текстфайл.ПолучитьТекст();

Если НоваяПустаяСтрока = "" Тогда
    Сообщить("После текстового документа работает");
Иначе
    Сообщить("После текстового документа не работает");
КонецЕсли;
Toveal commented 11 months ago

Выяснил что это пустой символ (код 0 в Unicode) И вот такой код отработает

УстановитьВнешнююКомпоненту("ОбщийМакет.FBReader");
ВК = ПодключитьВнешнююКомпоненту("ОбщийМакет.FBReader", "FBReader", ТипВнешнейКомпоненты.Native);
ВК = Новый("AddIn.FBReader.TestStr"); 

ПростоПустаяСтрока = ВК.ПолучитьПустуюСтроку();

Если ПростоПустаяСтрока = Символ(0) Тогда
    Сообщить("Пустая строка реально пустая!");
Иначе
    Сообщить("Пустая строка не пустая? Хмм");
КонецЕсли;
Sebekerga commented 11 months ago

Попробовал под Linux, ВК.ПолучитьПустуюСтроку() = "" и СтрДлина(ВК.ПолучитьПустуюСтроку()) = СтрДлина(""), странно. Я еще гляну на винде на днях. Пока можете еще дать инфы? Что выплюнет СтрДлина(ВК.ПолучитьПустуюСтроку())?

Не могу код с линукса нормально скопипастить, к сожалению, т.к. у меня обучающая лицензия.

Toveal commented 11 months ago

Попробовал под Linux, ВК.ПолучитьПустуюСтроку() = "" и СтрДлина(ВК.ПолучитьПустуюСтроку()) = СтрДлина(""), странно. Я еще гляну на винде на днях. Пока можете еще дать инфы? Что выплюнет СтрДлина(ВК.ПолучитьПустуюСтроку())?

Не могу код с линукса нормально скопипастить, к сожалению, т.к. у меня обучающая лицензия.

Выдает 1

Toveal commented 11 months ago

Кажется проблема в функции native_api_1c_core::ffi::string_utils::os_string_nil (ветка windows)

А именно в chain(Some(0).into_iter())

Из-за этого мы получаем вместо пустой строки символ 0 и если написать строку в 1С (например "Привет") то "Привет" из компоненты не будет равен тому что написано в 1С

Sebekerga commented 11 months ago

Почти наверняка, что так. Если у вас есть возможность потестить, было бы здорово - я до конца недели не смогу уделить время.

Sebekerga commented 11 months ago

Попробовал, просто удалить чеин нуля не получится.

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

Sebekerga commented 11 months ago

Данная ошибка была исправлена в PR, пока что только в dev канале, на выходных, надеюсь, перенесу в основной и на crates.io