Re[19]: Вызов событий COM из разных потоков
От: Мизантроп  
Дата: 26.11.09 16:40
Оценка:
Здравствуйте, Аркадий, Вы писали:

Вы поймите, код Вашего приложения видите Вы, но его не видят те, кто читает Ваши посты на форуме. Ваше последнее сообщение порождает опять больше вопросов, чем даёт ответов. Например, откуда у Вас взялся файл с секретным именем "..._TLB.h"? Вам его кто-то подарил? Вы импортировали чью-то библиотеку типов? Вы сами создали библиотеку типов?

А>Да, но доступ до тела Fire_OnMessage у меня есть, и я по нему "хожу" дебаггером и смотрю, что по всем своим вызовам он проходится. Один из вызовов в Fire_OnMessage — это OnMessage() интерфейса IUpEvents, который отрабатывается, не давая никакой реакции. Но доступа до тела IUpEvents у меня нет, т.к. он передавался от клиента, через advise().


А>При этом если Fire_OnMessage выполняется в основном потоке сервера, то OnMessage интерфейса IUpEvents отрабатывается.


Если метод вызывается, значит он вызывается. Точка. Всё остальное зависит от реализации этого метода, и если у Вас нет доступа к этой реализации, то поделать Вы ничего не сможете. Остаётся, правда, не ясно — проверяете ли Вы результат вызова функций, в частности функций маршалинга и демаршалинга IUpEvents, и поддерживает ли этот интерфейс маршалинг вообще.

Я, например, понятия не имею, какие обёртки генерит билдер, и что, например, будет делать эта обёртка при отсутствии у неё реальной ссылки на внешний интерфейс.

А>Я его получаю при создании объекта (Up) через Wizard Builder-а, указав, что объекту нужны события.


Кого — его? Через какой визард? Создания объекта с поддержкой событий? Или создания обёртки для чужого событийного интерфейса?

В общем, в таком духе. Старайтесь сами себе задавать подобные вопросы, когда описываете проблему, тем более что спрашивал-то я не это, а кто, где и как создаёт инстанс, реализующий IUpEvents.

Давайте я попробую изложить то, что мне подсказывает телепатия, а Вы поправите там, где я неправ.

У Вас есть eхе-приложение. В нём определён некий COM-объект с поддержкой событий через интерфейс то-ли IUpEvents, то-ли IUpTaskEvents. Внешний клиент создаёт экзэмпляр этого объекта и подписывается на его события, передав реализованный этим клиентом интерфейс IUpEvents (или IUpTaskEvents?). В ответ Ваш COM объект загружает DLL, которой передаёт свой интерфейс IMyEvents. DLL создаёт доп. поток и из этого потока вызывает методы интерфейса IMyEvents. Метод IMyEvents.OnMessage Вашего COM-объекта вызывает функцию Fire_OnMessage, которая, в свою очередь, должна вызвать
IUpEvents.OnMessage.

Так? В методе Advise Вы маршалируете пришедший извне IUpEvents с помощью GIT. В Fire_OnMessage Вы его демаршалируете и пытаетесь вызвать его метод. Так? Если Advise вызывается в потоке-члене MTA (а именно так и должно быть судя по Вашим словам), и Fire_OnMessage вызывается членом MTA, то маршалинг между ними не нужен, всё и так обязано работать. Но и помешать он тоже не может, при демаршалинге Вы должны получить тот самый экзэмпляр интерфейсной ссылки, который маршалировали. В этом можно убедиться, просто сравнив эти ссылки друг с другом как целые или указатели.

Прежде всего убедитесь, что Вы проверяете результат всех вызываемых Вами функций, прежде всего тех, которые возвращают HResult. Далее убедитесь, что все переменные инициализируются валидными значениями. Например, если Вы намерены получить от функции интерфейс, то перед Вызовом запишите в переменную NULL, а после убедитесь, что она изменила своё значение.

Потому, что чудес не бывает, и "Если метод вызывается, значит он вызывается. Точка".
"Нормальные герои всегда идут в обход!"
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.