![]() |
|
![]() ![]() ![]() |
|
al_capone |
|
||||
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 14.7.2007 Репутация: нет Всего: нет |
Добрый вечер.
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 |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 5 Всего: 118 |
как я понимаю ситуацию: у вас есть блокирующий вызов 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 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 14.7.2007 Репутация: нет Всего: нет |
нет, извиняюсь за весьма непонятный код, нужно было упростить код и все не нужное отсеять. Наверное слово proxy вас отвлекает от истины. Ситуация такая: чтобы не делать весьма непонятные мне вещи типа маршалинга, я сделал отдельный поток для работы с ком объектом, в этом потоке я его создаю, потом подключаюсь к событиям, потом вызываю connect com объекта. с этого момента данные должны приходить через события. через некоторое время делается дисконект в этом же потоке, и и ком объект уничтожается. т.е. с объектом работает только один поток и только одна функция (код которой в первом комменте).
|
|||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 8 Всего: 223 |
По п1 - что такое CATLinitializer ? Сдается мне, что оно должно быть в main.
По п2 нужно сделать цикл обработки сообщений (GetMessage/ProcessMessage) вместо MessageBox (или отказаться от ATM, сделать например FreeThreaded, но может и не помочь) |
|||
|
||||
al_capone |
|
|||
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 14.7.2007 Репутация: нет Всего: нет |
1)вот
2)а можно пример как сделать обработчик сообщений? просто смотри, у меня это все происходит в длл, причем в таком что там нет ни mfc ни com ни atl. Это единственная функция где используется что то такое. |
|||
|
||||
xvr |
|
||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 8 Всего: 223 |
1) Строка 22 (m_hrATL = _Module.Init(NULL, GetModuleHandle(NULL));) здесь лишняя - ее надо выполнить только 1 раз на всю программу, а не каждый раз на каждый thread
2) Обработчик совершенно стандартный:
|
||||
|
|||||
al_capone |
|
|||
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 14.7.2007 Репутация: нет Всего: нет |
ок, большое спасибо, работает!!! основная проблема решена.
Теперь выявилась еще одна проблема, компонента работает нестабильно, после первого фрейма уходит в нирвану, потом в output вылезают ошибки типа тайм-аут сработал. Если этот самый код поместить в mfc exe (например при нажатии кнопки чтобы выполнялось все) то так работает отлично. Я знаю что информации явно недостаточно но соображения есть где копать? еще раз, спасибо! |
|||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 8 Всего: 223 |
Причин может быть вагон и маленькая тележка ![]() Нужна более подробная информация о программе |
|||
|
||||
![]() ![]() ![]() |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: COM/DCOM/ActiveX/ATL/CORBA | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |