Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: COM/DCOM/ActiveX/ATL/CORBA > Проблема с событиями в com |
Автор: al_capone 25.2.2009, 18:34 | ||||
Добрый вечер. Cразу хочу предупредить, что я новичок в com. Есть ActiveX c ThreadingModel=Apartment. Он может получать данные из сети, а прочитанные данные возвращать через events. Я написал функцию которую крутит отдельный поток:
тут создается объект COM от которого идут события (VWDataAccessCtrl ), создается объект CVWEventsProxy отнаследованный от IDispEventImpl, и в конструкторе он еще подключается к pDataAcces. Т.е. события должны приходить в eventsProxy. Я столкнулся с двумя проблемами в этом коде: 1)Когда эта функция один раз отрабатывает, поток уничтожается, когда же я заново создаю поток и выполняется этот код, при инициализации COM (CoInitialize(NULL)) в дебаге выскакивает противный assert вот в этом месте
после него CoInitialize возвращает S_OK. Соответственно в релизе никаких нареканий в работе нет. Что мне с этим делать? 2)Основная проблема: Если я уберу MessageBox и поставлю sleep, например, или буду делать что то левое, то события не вызываются.Насколько я понял, когда я создаю “STA поток”, то в этом потоке выполняется и обработчик сообщений (оконные сообщения) для обектов com (насколько я понял events вызываются в ответ на сообщения). Когда же я делаю sleep() (или любое другое действие). Поток приостанавливается и обработчик соответственно тоже, поэтому не работает. (не вдумываетесь в последние 2 предложения) Если вам лень объяснять что и почему, буду рад просто ссылке, но именно по теме. Спасибо за внимание. |
Автор: jonie 26.2.2009, 09:11 |
как я понимаю ситуацию: у вас есть блокирующий вызов accept(), и после коннекта вы делаете новый поток, куда пропихиваете COMобъект MyClass через параметр pParam. Так делать нельзя - у вас MyClass создан в потоке не принадлежащему апартаменту где создан объект (у вас же STA, а не MTA => один поток на апартамент). Для проброса нужно использовать маршалинг(CoMarshal чета тут функцию) (или, если вы точно уверены что делаете, и у вас inproc сервер, тогда можно GIT использовать (появилось в win2000 вроде) (и получать указатель уже через cookie)) - гугл по слову RegisterInterfaceInGlobal. http://www.compdoc.ru/prog/cpp/com/ch5/ch510.shtml |
Автор: al_capone 26.2.2009, 09:57 |
нет, извиняюсь за весьма непонятный код, нужно было упростить код и все не нужное отсеять. Наверное слово proxy вас отвлекает от истины. Ситуация такая: чтобы не делать весьма непонятные мне вещи типа маршалинга, я сделал отдельный поток для работы с ком объектом, в этом потоке я его создаю, потом подключаюсь к событиям, потом вызываю connect com объекта. с этого момента данные должны приходить через события. через некоторое время делается дисконект в этом же потоке, и и ком объект уничтожается. т.е. с объектом работает только один поток и только одна функция (код которой в первом комменте). |
Автор: xvr 26.2.2009, 15:21 |
По п1 - что такое CATLinitializer ? Сдается мне, что оно должно быть в main. По п2 нужно сделать цикл обработки сообщений (GetMessage/ProcessMessage) вместо MessageBox (или отказаться от ATM, сделать например FreeThreaded, но может и не помочь) |
Автор: al_capone 26.2.2009, 15:45 | ||
1)вот
2)а можно пример как сделать обработчик сообщений? просто смотри, у меня это все происходит в длл, причем в таком что там нет ни mfc ни com ни atl. Это единственная функция где используется что то такое. |
Автор: xvr 26.2.2009, 19:33 | ||||
1) Строка 22 (m_hrATL = _Module.Init(NULL, GetModuleHandle(NULL));) здесь лишняя - ее надо выполнить только 1 раз на всю программу, а не каждый раз на каждый thread 2) Обработчик совершенно стандартный:
|
Автор: al_capone 26.2.2009, 20:06 |
ок, большое спасибо, работает!!! основная проблема решена. Теперь выявилась еще одна проблема, компонента работает нестабильно, после первого фрейма уходит в нирвану, потом в output вылезают ошибки типа тайм-аут сработал. Если этот самый код поместить в mfc exe (например при нажатии кнопки чтобы выполнялось все) то так работает отлично. Я знаю что информации явно недостаточно но соображения есть где копать? еще раз, спасибо! |
Автор: xvr 26.2.2009, 21:07 | ||
Причин может быть вагон и маленькая тележка ![]() Нужна более подробная информация о программе |