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

М>Здравствуйте, silart, Вы писали:


S>>Если ты в каком-то потоке создашь GIT, сохранишь указатель на него и будешь его использовать из другого потока, то работать не будет. По крайней мере у меня так не работало. GIT нужно создавать в тот моент когда он становится нужен.


М>Вероятно, Вы что-то не так сделали. Стандартный GIT — объект с нейтральной моделью, то есть получив его интерфейс в одном апартаменте, этот интерфейс затем можно использовать в любом другом апартаменте. Фактически метод RegisterInterfaceInGlobal создаёт стрим на HGlobal, маршалирует в него интерфейс с помощью CoMarshalInterface, и сохраняет HGlobal в своём внутреннем списке. Метод GetInterfaceFromGlobal по куку ищет HGlobal, опять из него создаёт стрим и вызывает CoUnmarshalInterface. Так что никаких препятствий для использования одной ссылки на IGlobalInterfaceTable из всех апартаментов нет.


Я пробовал и инициализировать новый указатель на GIT в каждом апартменте, и использовать один, инициализированный в одном — результат одинаков. Что-то не так — это что? Может быть, я перечислю, что есть, а Вы сможете подсказать, где там может быть ошибка?

Есть DLL, внутри которой крутится поток. На вход эта DLL принимает интерфейс IMyEvents, дергая его методы тогда, когда мне нужны события. Реализовано всё руками и всё можно переделать. Интерфейс этот содержит три метода OnStart (перед стартом цикла прослушивания сообщений), OnMessage (если пришло сообщение) и OnFinish (после завершения цикла прослушивания сообщений). Все эти события вызываются в моем доп потоке DLL.

Далее есть .exe КОМ сервер, который цепляет эту ДЛЛ. Он реализует метод OnStart — добавляя туда CoInitializeEx(NULL, MultiThreaded..), реализует метод OnFinish, добавляя туда CoUninitialize(); , и реализует метод OnMessage, добавляя туда обертку Fire_OnMessage уже своего событийного интерфейса (чтобы отрабатывалось событие).

Все методы IMyEvents выполняются в дополнительном потоке... сначала там выполнится CoInitializeEx(...), потом события, достающиеся из GIT (это зашито в Fire_OnMessage) потом CoUninitialize().

Что тут может быть не так? Правильно я понимаю, что клиент на VBA должен цеплять эти события?
С уважением, Аркадий.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.