Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Горячая тема (более 10 ответов) "Плохой тип переменной" (число прочтений - 6480 )
chessman
God Member
*****
Отсутствует



Сообщений: 1084
Зарегистрирован: 10. Августа 2007
"Плохой тип переменной"
12. Ноября 2010 :: 10:42
Печать  
Хочу разобраться с этой ошибкой...

Правильно ли я понимаю, что когда мы в com-объект (obj1) пытаемся передать 1C-объект(obj2),  в IDispatch_Invoke obj1 приезжает завернутый в Variant IDispatch obj2. А что дальше происходит - obj1 проверяет clsid и поддерживаемые obj2 интерфейсы? И вообще, в каком месте проверяется тип приезжающего объекта?

Заранее спасибо.
  
Наверх
 
IP записан
 
trad
1c++ power user
1c++ donor
1c++ moderator
Отсутствует



Сообщений: 3046
Местоположение: Киров
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: "Плохой тип переменной"
Ответ #1 - 12. Ноября 2010 :: 19:25
Печать  
а в чем конкретно проблема?
  

1&&2&&3
Наверх
 
IP записан
 
chessman
God Member
*****
Отсутствует



Сообщений: 1084
Зарегистрирован: 10. Августа 2007
Re: "Плохой тип переменной"
Ответ #2 - 12. Ноября 2010 :: 19:41
Печать  
Чисто в понимании процесса передачи параметров в сом-об'ект. Хочется понять, кто к кому при помощи какого интерфейса... На пальцах, чтоб было попонятнее.
  
Наверх
 
IP записан
 
trad
1c++ power user
1c++ donor
1c++ moderator
Отсутствует



Сообщений: 3046
Местоположение: Киров
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: "Плохой тип переменной"
Ответ #3 - 12. Ноября 2010 :: 19:51
Печать  
Ну ты все правильно сказал:
Любой агрегатный объект 1С преобразуется в специальный контекст реализующий IDispatch (и только этот интерфейс). Этот IDispatch в варианте передается в инвок.
Ну а каким испытаниям будет подвержен наш IDispatch известно только разработчикам принимающей стороны. Т.е. фиг его знает Улыбка
  

1&&2&&3
Наверх
 
IP записан
 
chessman
God Member
*****
Отсутствует



Сообщений: 1084
Зарегистрирован: 10. Августа 2007
Re: "Плохой тип переменной"
Ответ #4 - 13. Ноября 2010 :: 07:18
Печать  
Отлично!

trad писал(а) 12. Ноября 2010 :: 19:51:
Любой агрегатный объект 1С преобразуется в специальный контекст реализующий IDispatch


Я так понимаю, речь о CBLExportContext?

Собственно, я хочу "научить" DynamicWrapperX принимать 1С-й объект, а в ответ мне возвращать указатель (число) на его IDispatch. А дальше, я думаю, из него можно получить всю необходимую инфу - *CBLContext, CValue.
  
Наверх
 
IP записан
 
trad
1c++ power user
1c++ donor
1c++ moderator
Отсутствует



Сообщений: 3046
Местоположение: Киров
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: "Плохой тип переменной"
Ответ #5 - 13. Ноября 2010 :: 08:11
Печать  
chessman писал(а) 13. Ноября 2010 :: 07:18:
Я так понимаю, речь о CBLExportContext?
да
  

1&&2&&3
Наверх
 
IP записан
 
chessman
God Member
*****
Отсутствует



Сообщений: 1084
Зарегистрирован: 10. Августа 2007
Re: "Плохой тип переменной"
Ответ #6 - 13. Ноября 2010 :: 13:29
Печать  
Как показали эксперименты, до внешнего com-оъекта, 1С-й объект не доезжает, исключение происходит в CStdOleBLContext::CallAsProc в Blang'е. Получается, что 1С-ка откуда-то сама знает, что это "плохой тип переменной".
« Последняя редакция: 13. Ноября 2010 :: 14:57 - chessman »  
Наверх
 
IP записан
 
trad
1c++ power user
1c++ donor
1c++ moderator
Отсутствует



Сообщений: 3046
Местоположение: Киров
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: "Плохой тип переменной"
Ответ #7 - 13. Ноября 2010 :: 16:46
Печать  
странно.
а ты уверен что исключение связано с передачей объекта в качестве параметра, а не с возвратом результата?
  

1&&2&&3
Наверх
 
IP записан
 
chessman
God Member
*****
Отсутствует



Сообщений: 1084
Зарегистрирован: 10. Августа 2007
Re: "Плохой тип переменной"
Ответ #8 - 14. Ноября 2010 :: 13:10
Печать  
trad писал(а) 13. Ноября 2010 :: 16:46:
странно.
а ты уверен что исключение связано с передачей объекта в качестве параметра, а не с возвратом результата?


Если IDA не ошибается, то происходит именно так, как написано выше. Получается, что в сторонние СОМ (не по технологии 1С) вообще нельзя передать 1С-й объект.
  
Наверх
 
IP записан
 
chessman
God Member
*****
Отсутствует



Сообщений: 1084
Зарегистрирован: 10. Августа 2007
Re: "Плохой тип переменной"
Ответ #9 - 14. Ноября 2010 :: 19:54
Печать  
Мои предположения подтвердились. 1С не хочет делиться с посторонним com, своим агрегатным объектом.
Это следует из кода CStdOleBLContext::CallAsProc и CStdOleBLContext::CallAsFunc.
В com мужно только передать объекты простых типов:
0 - неопределенный тип данных;
1 - числовой тип данных;
2 - строковый тип данных;
3 - тип данных Дата;

Агрегатные объекты имеют след. типы:
10 - агрегатный тип данных 'Перечисление';
11 - агрегатный тип данных 'Справочник';
12 - агрегатный тип данных 'Документ';
13 - агрегатный тип данных 'Календарь';
14 - агрегатный тип данных 'ВидРасчета';      
100 - внешний объект ('Текст', 'Таблица', 'Запрос', 'ЖурналРасчетов' и т.п.).

Если в CallAsProc/CallAsFunc "привести" агрегатные типы к простым битовой операцией AND, то после этого, в com, в IDispatch::Invoke приезжает Перечисление, как строка, Справочник как дата, Документ как Неопределенный тип и т.д.
И в принципе, с этим уже можно что-то делать.


  
Наверх
 
IP записан
 
chessman
God Member
*****
Отсутствует



Сообщений: 1084
Зарегистрирован: 10. Августа 2007
Re: "Плохой тип переменной"
Ответ #10 - 16. Ноября 2010 :: 16:42
Печать  
В качестве бреда...поправил Blang.dll
Появилась возможность выполнять подобный "код":


Передаем в сом-объект 1C-ю Форму

Код
Выбрать все
Перем Wrap;
Перем МД;

Процедура Подготовить(buf, ECX, Addr)	// для соглашения вызова thiscall, в ecx - указатель на объект
	Wrap.NumPut(МД.СтрокаВЧисло("B9", 16), buf, 0, "b");	// mov ecx, ....
	Wrap.NumPut(ECX, buf, 1);								// *CBLContext
	Wrap.NumPut(МД.СтрокаВЧисло("E9", 16), buf, 5, "b");	// jmp ...Addr
	Wrap.NumPut(Addr - (buf + 6 + 4), buf, 6);
КонецПроцедуры

Процедура Сформировать()
	buf	   = Wrap.GlobalAlloc(64, 256);

	// Передаем объект "Форма"
	pCValue     = Wrap.NumGet(Форма);

	pCBLContext = Wrap.NumGet(pCValue + МД.СтрокаВЧисло("48", 16)); // +48h
	vtable 		= Wrap.NumGet(pCBLContext);
	If pCBLContext <> 0 Then
		//CBLContext::GetNMethods
		vfunс = Wrap.NumGet(vtable + МД.СтрокаВЧисло("64", 16));
		Подготовить(buf, pCBLContext, vfunс);
		Wrap.RegisterAddr(buf, "GetNMethods", "f=s", "r=l");
		NMethods = Wrap.GetNMethods();

		//CBLContext::GetMethodName
		vfunс = Wrap.NumGet(vtable + МД.СтрокаВЧисло("6C", 16));
		Подготовить(buf, pCBLContext, vfunс);
		Wrap.RegisterAddr(buf, "GetMethodName", "i=ll", "r=s");
		For j = 0 To NMethods -1  Do
			MethodName = Wrap.StrGet(Wrap.GetMethodName(j, 1));
			Message(MethodName);
		EndDo;
	EndIf;

	Wrap.GlobalFree(buf);
КонецПроцедуры

Wrap = СоздатьОбъект("DynamicWrapperX");
Wrap.Register("Kernel32", "GlobalAlloc" , "i=ll", "r=u");
Wrap.Register("Kernel32", "GlobalFree" , "i=h", "r=l");

МД = СоздатьОбъект("MetaDataWork");
 



Печатает методы объекта Форма
  
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: "Плохой тип переменной"
Ответ #11 - 17. Ноября 2010 :: 08:07
Печать  
Прикольно Улыбка
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать