Помогите разобраться в COM

Общие вопросы, не зависящие от языка реализации.

Модераторы: Duncon, Hawk, Romeo, Eugie

Ответить
ivs4
Сообщения: 4
Зарегистрирован: 15 сен 2005, 21:37

15 сен 2005, 21:50

Вроде бы делаю все просто.
1. Создаю в Delphi библиотеку типов TESTOBJECT. В ней создаю объект TEST и интерфейс ITEST. В интерфейсе ITEST создаю метод T().
2. Далее оаботаю в VC++6.0. Создаю мастером класс ITEST на основе созданной в Delphi библиотеки типов TESTOBJECT.tlb. Пишу код:

Код: Выделить всё

HRESULT hres;
	hres=CoInitialize(NULL);
	CLSID gdc,gdi;
	ITEST *p;
	//{A6A5385D-EE97-491D-9AFC-9AB42C3CFD73}
	gdc.Data1 =0xA6A5385D;
	gdc.Data2=0xEE97;
	gdc.Data3=0x491D;
	gdc.Data4 [0]=0x9A;
	gdc.Data4 [1]=0xFC;
	gdc.Data4 [2]=0x9A;
	gdc.Data4 [3]=0xB4;
	gdc.Data4 [4]=0x2C;
	gdc.Data4 [5]=0x3C;
	gdc.Data4 [6]=0xFD;
	gdc.Data4 [7]=0x73;
	
	//{2B1B3976-0DB2-45BA-9F0B-E6AD291012AD}
	gdi.Data1 =0x2B1B3976;
	gdi.Data2=0x0DB2;
	gdi.Data3=0x45BA;
	gdi.Data4 [0]=0x9F;
	gdi.Data4 [1]=0x0B;
	gdi.Data4 [2]=0xE6;
	gdi.Data4 [3]=0xAD;
	gdi.Data4 [4]=0x29;
	gdi.Data4 [5]=0x10;
	gdi.Data4 [6]=0x12;
	gdi.Data4 [7]=0xAD;
	tagVARIANT tvar;
	tvar.boolVal = true;

	hres=CoCreateInstance(gdc,NULL,1,gdi,(void**)&p);
	if (hres!=S_OK)
	{
		MessageBox("ERROR");
	}
	else
	{
		((ITEST*)p)->T();

	}
	CoUninitialize(); 

Результат:вываливается ошибка доступа к памяти.
CoCreateInstance отрабатывает без ошибок и возвращает адрес интерфейса. Спотыкаюсь на вызове метода. Склоняюсь к мысли, что некорректно создается класс на основе библиотеки типов. Большая просьба помочь разобраться начинающему изучать COM.
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

16 сен 2005, 11:31

1. В дебаги просмотри адреса виртуальных методов указателя ITEST, все корректные?
2. Вместо такого ужасного задания CLSID, можно просто писать __uuidof(TEST), __uuidof(ITEST) прямо в вызове CoCreateInstance.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Sera
Сообщения: 38
Зарегистрирован: 03 мар 2005, 17:23
Откуда: Симферополь

16 сен 2005, 11:44

1. Если у тебя
ITEST *p;
то зачем ты снова приводишь p к типу ITEST* : ((ITEST*)p)->T(); ?

2. Скорее всего ошибка как раз в методе ITest::T(). Ты ведь сам создавал его? Вот и пересмотри его.
ivs4
Сообщения: 4
Зарегистрирован: 15 сен 2005, 21:37

16 сен 2005, 16:59

2. Скорее всего ошибка как раз в методе ITest::T(). Ты ведь сам создавал его? Вот и пересмотри его.
Не думаю. Тот же объект из VB работает нормально.

Код: Выделить всё

set t=createobject("TESTOBJECT.TEST")
t.T
Sera
Сообщения: 38
Зарегистрирован: 03 мар 2005, 17:23
Откуда: Симферополь

16 сен 2005, 20:14

Тогда вполне вероятно, что ты запутался в этих UUID-ах и выписал для интерефейса ITest неверный.
Тогда все сходится -- CoCreateInstance отрабатывает, возвращает указатель на интерфейс, только на другой.
То есть замени эти кошмарные определения CLSID gdc,gdi; на __uuidof(...) & __uuidof(ITest)


Кстати, у тебя не хватает одного Release-а:
else
{
p->T();
p->Release();
}

Иначе COM под хвост пойдет...
Ответить