Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

В версии 1.8 сломался возврат результатов функций через COM #1376

Closed
tormozit opened this issue Nov 2, 2023 · 24 comments

Comments

@tormozit
Copy link

tormozit commented Nov 2, 2023

Опишите ошибку
сломался возврат результатов функций через COM видимо в процессе починки возврата значений параметров этих же функций
#1324

Воспроизведение ошибки

ф = Новый COMОбъект("V83.Application");
СтрокаСоединения = <Строка соединения с любой базой 1С>;
ф.Connect(СтрокаСоединения);
я = ф.Метаданные.Справочники.Количество();

получаем ошибку

ScriptEngine.Machine.ExternalSystemException: {Модуль D:\Projects\TurboConf\TurboConf.HostApplication\bin\Debug\user_scripts\SampleCOM.os / Ошибка в строке: 119 / Внешнее исключение (System.NullReferenceException): Ссылка на объект не указывает на экземпляр объекта.}
я = ф.Метаданные.Справочники.Количество();
---> System.NullReferenceException: Ссылка на объект не указывает на экземпляр объекта.
в ScriptEngine.Machine.Contexts.UnmanagedCOMWrapperContext.CallAsFunction(Int32 methodNumber, IValue[] arguments, IValue& retValue)
в ScriptEngine.Machine.MachineInstance.ResolveMethodFunc(Int32 arg)
в ScriptEngine.Machine.MachineInstance.MainCommandLoop()
--- Конец трассировки внутреннего стека исключений ---
в ScriptEngine.Machine.MachineInstance.MainCommandLoop()
в ScriptEngine.Machine.MachineInstance.ExecuteCode()
в ScriptEngine.Machine.MachineInstance.ExecuteMethod(IRunnable sdo, Int32 methodIndex, IValue[] arguments)
в ScriptEngine.Machine.Contexts.ScriptDrivenObject.CallAsFunction(Int32 methodNumber, IValue[] arguments, IValue& retValue)
в TurboConf.HostApplication.HostApplicationForm.ExecuteScript(Script script, Keys ctrl, Keys alt, Keys shift, ScreenForm statusForm, String entryPoint, IVariable[] parameters, ScriptOptions options) в D:\Projects\TurboConf\TurboConf.HostApplication\HostApplicationForm.cs:строка 253

@tormozit tormozit changed the title 1.8 сломался возврат результатов функций через COM В версии 1.8 сломался возврат результатов функций через COM Nov 2, 2023
@EvilBeaver EvilBeaver added this to the v2.0-RC4 milestone Nov 3, 2023
@tormozit
Copy link
Author

tormozit commented Nov 6, 2023

В ветку 1.8 будет вливаться?

@nixel2007
Copy link
Collaborator

ветка latest - это 1.х

@EvilBeaver EvilBeaver reopened this Nov 6, 2023
@tormozit
Copy link
Author

tormozit commented Nov 7, 2023

Киньте ссылку на установщик или архив с проблемной версией 1.9

@EvilBeaver
Copy link
Owner

@tormozit
Copy link
Author

tormozit commented Nov 7, 2023

Проверил на чистом движке ОСкрипт 1.9 (без Турбоконфа) по ссылке выше.
Ошибки нет. Тест приложен.

ф = Новый COMОбъект("V83.Application");
СтрокаСоединения = "File=""C:\1C\DB\ИР Подсистема 8.3"";usr=1";
ф.Connect(СтрокаСоединения);
Пар1 = 1;
Рез = ф.ирКэш.ПолеТекстаПрограммы(Пар1);
Сообщить("1");

@bolsun
Copy link

bolsun commented Nov 7, 2023

Проверил на чистом движке ОСкрипт 1.9 (без Турбоконфа) по ссылке выше. Ошибки нет. Тест приложен.

ф = Новый COMОбъект("V83.Application");
СтрокаСоединения = "File=""C:\1C\DB\ИР Подсистема 8.3"";usr=1";
ф.Connect(СтрокаСоединения);
Пар1 = 1;
Рез = ф.ирКэш.ПолеТекстаПрограммы(Пар1);
Сообщить("1");

Данный тест в ТурбоКонф тоже работает, в таком варианте:

Процедура РедактироватьТекст()	

	ПодключениеИР = ПодключениеИР(,, Ложь);
	Если ПодключениеИР = Неопределено Тогда
		Возврат;
	КонецЕсли;
	Если Не ЗначениеЗаполнено(ТекстМодуля) Тогда
		Возврат;
	КонецЕсли;
	МодулиИР = МодулиИР(ПодключениеИР);

	Пар1 = 1;
	Рез = МодулиИР.ирКэш.ПолеТекстаПрограммы(Пар1);
	Сообщить("Работает!");
	Возврат;

Если закомментировать Возврат - происходит ошибка:
Ошибка в строке: 1130 / Внешнее исключение (System.NullReferenceException): Ссылка на объект не указывает на экземпляр объекта.}

@bolsun
Copy link

bolsun commented Nov 7, 2023

Строка 1130 такая:
ЗаголовокОкна = ТурбоКонф.ПолучитьЗаголовокТекущегоОкна();

@EvilBeaver
Copy link
Owner

Объект "Турбоконф", как я понимаю, не объект движка. Смотреть надо в его веутренности и в реализацию метода ПолучитьЗаголовок...

@bolsun
Copy link

bolsun commented Nov 7, 2023

Объект "Турбоконф", как я понимаю, не объект движка. Смотреть надо в его веутренности и в реализацию метода ПолучитьЗаголовок...

    [ContextMethod("ПолучитьЗаголовокТекущегоОкна", "GetForegroundWindowTitle")]
    public string GetWindowTitle()
    {
        return User32.GetText(User32.GetForegroundWindow());
    }

@bolsun
Copy link

bolsun commented Nov 7, 2023

Не факт, что это именно эта строка. Т.к. мы выяснили, что иногда они не совпадают. Проверю отладчиком.

@bolsun
Copy link

bolsun commented Nov 7, 2023

Да, строка не та.
Падает здесь:

Функция ПолеТекстаПрограммыИР(ПодключениеИР, ТекстМодуля, ПозицияВТексте, ВыделенныйТекст = "", ПереходитьВоВложенныйКонтекст = Истина, Знач КакВызовМетода = Неопределено,
	Знач ЭтоДокумент = Истина, Знач СИменемКонфигурации = Ложь, Знач ЭтоАвтодополнение = Ложь, Знач ИдентификаторПоля = Неопределено, Знач ИмяКонфигурации = "")

	Если ЭтоДокумент Тогда
		Попытка
			ТекущийДокумент = Конфигуратор.ТекущийДокумент;
		Исключение
		КонецПопытки;
		Если ЗначениеЗаполнено(ТекущийДокумент) Тогда
			ЗаголовокОкна = ТекущийДокумент.Заголовок;
			ИмяКонфигурации = ТекущийДокумент.ИмяКонфигурации;
			ИдентификаторПоля = ТекущийДокумент.DocumentRuntimeId;
		//   Сообщить(ТекущийДокумент.ConfRuntimeId);  
		КонецЕсли;
	КонецЕсли;
	МоментЗапуска = ТекущаяУниверсальнаяДатаВМиллисекундах();
	ПолноеИмяМодуля = "";
	ЭтоМодульВнешнегоОбъекта = Ложь;
	КлючКэша = "ПолеТекстаПрограммы";
	ПолеТекстаПрограммы = ВосстановитьЗначениеСеансаКонфигуратора(КлючКэша);
	Попытка
		Пустышка = ПолеТекстаПрограммы.мИмяМодуля;
	Исключение
		ПолеТекстаПрограммы = Неопределено;
	КонецПопытки;
	Если ПолеТекстаПрограммы = Неопределено Тогда
		МодулиИР = МодулиИР(ПодключениеИР);
		ПолеТекстаПрограммы = МодулиИР.ирКэш.ПолеТекстаПрограммы(ЯзыкПрограммы);

@bolsun
Copy link

bolsun commented Nov 7, 2023

image

@bolsun
Copy link

bolsun commented Nov 7, 2023

image

@tormozit
Copy link
Author

tormozit commented Nov 7, 2023

Если фактический параметр вызываемого COM метода имеет значение "Неопределено", то на чистом движке ОСкрипт 1.9 (без Турбоконфа) у меня то же возникает ошибка в тесте:

ф = Новый COMОбъект("V83.Application");
СтрокаСоединения = "File=""C:\1C\DB\тест1"";usr=1";
ф.Connect(СтрокаСоединения);
Пар1 = Неопределено;
Рез = ф.Сообщить(Пар1);

{Модуль C:\TerminalDisk\comtest.os / Ошибка в строке: 5 / Внешнее исключение (System.NullReferenceException): Ссылка на объект не указывает на экземпляр объекта.}

@EvilBeaver
Copy link
Owner

@tormozit принял, посмотрю, что можно сделать. Спасибо за исследование. Но стоит понимать, что Неопределено языка BSL в этом случае передается в COM-объект, а он не знает ничего про Неопределено, Неопределено транслируется в "NULL общего назначения" и дальше уже падает сам COM-объект, который там null не ожидает. Мне кажется, можно там что-то отрегулировать, но не уверен, что удастся

@bolsun
Copy link

bolsun commented Nov 8, 2023

@tormozit принял, посмотрю, что можно сделать. Спасибо за исследование. Но стоит понимать, что Неопределено языка BSL в этом случае передается в COM-объект, а он не знает ничего про Неопределено, Неопределено транслируется в "NULL общего назначения" и дальше уже падает сам COM-объект, который там null не ожидает. Мне кажется, можно там что-то отрегулировать, но не уверен, что удастся

Т.к. этот же код работает в 1.7, то вроде шансы есть ))

@Mr-Rm
Copy link
Collaborator

Mr-Rm commented Nov 8, 2023

Тест @tormozit падает тут:

if (flags[i] && !initialValues[i].Equals(values[i]))

с исключением
System.NullReferenceException: 'Ссылка на объект не указывает на экземпляр объекта.'
initialValues[] was null.

@EvilBeaver
Copy link
Owner

initialValues не может быть null, он создается перед вызовом всегда... Странно

@Mr-Rm
Copy link
Collaborator

Mr-Rm commented Nov 8, 2023

На самом деле initialValues[0]==null, но сообщение Студии именно такое.
И да, причина падения в маршалинге Неопределено в null, но не из-за передачи его в COM, а из-за попытки возврата параметра.

@EvilBeaver
Copy link
Owner

Да, уже починил

@Mr-Rm
Copy link
Collaborator

Mr-Rm commented Nov 8, 2023

Кажется, можно уронить и это исправление...

@Mr-Rm
Copy link
Collaborator

Mr-Rm commented Nov 8, 2023

В примере делаем

Пар1 = NULL;

и получаем
Ошибка в строке: 5 / Тип ScriptEngine.Machine.Variable не поддерживает преобразование в CLR-объект

@EvilBeaver
Copy link
Owner

Ну это не совсем ошибка так-то... Null это же субд-шный литерал, отличный от Неопределено. И текст исключения честный

@EvilBeaver
Copy link
Owner

Закрываю, кажется что худо-бедно, но исправлено.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

When branches are created from issues, their pull requests are automatically linked.

5 participants