Russian Qt Forum
Ноябрь 22, 2024, 18:07 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Работа с COM в MTA и QApplication  (Прочитано 8562 раз)
Dolu
Гость
« : Октябрь 21, 2014, 14:36 »

Добрый день!

Проблема: нужно работать с COM-объектом в многопоточной среде. COM обёрнут QAxObject.
В консольном приложении (QCoreApplication) всё хорошо, но при создании QApplication, начинается беда.
Дело в том, что в конструкторе QApplication происходит вызов OleInitialize(NULL), а он за собой тянет вызов CoInitializeEx(NULL, COINIT_APARTMENTTHREADED), и в этом случае из других потоков доступа к COM нет :-(
Если после создания QApplication, переинициализировать COM:
CoUninitialize();
CoInitializeEx( NULL, COINIT_MULTITHREADED );
то перестают вызываться QFileDialog, например... и вообще много, что перестаёт работать.

Сталкивался ли кто с данной проблемой и существует ли её решение?
Записан
Johnik
Крякер
****
Offline Offline

Сообщений: 339


Просмотр профиля
« Ответ #1 : Октябрь 21, 2014, 23:23 »

какая ось?
Записан
Dolu
Гость
« Ответ #2 : Октябрь 22, 2014, 07:41 »

какая ось?
не принципиально, думаю, что как на NT 5.1 так и на NT 6.3 будет одинаково...
Записан
Johnik
Крякер
****
Offline Offline

Сообщений: 339


Просмотр профиля
« Ответ #3 : Октябрь 22, 2014, 08:13 »

думаю, что как на NT 5.1 так и на NT 6.3 будет одинаково...
проверяли?

Работа COM подсистемы во многом отличается в XP с системами выше, в некоторых случаях это связано с DEP.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #4 : Октябрь 22, 2014, 08:20 »

Сталкивался ли кто с данной проблемой и существует ли её решение?
Попробуйте в других нитках, где будете работать с COM-объектами, в начале выполнять CoInitializeEx( NULL, COINIT_MULTITHREADED ).
Записан
Dolu
Гость
« Ответ #5 : Октябрь 22, 2014, 08:37 »

Попробуйте в других нитках, где будете работать с COM-объектами, в начале выполнять CoInitializeEx( NULL, COINIT_MULTITHREADED ).
Пробовал, нет доступа. :-(
У меня объект существует ещё до создания потоков... и маршалить его ручками в поток не очень хочется...

проверяли?
на XP не проверял, только win7 и 2008r2, одинаково... :-(
Записан
Dolu
Гость
« Ответ #6 : Октябрь 22, 2014, 08:45 »

Единственное, что придумал, это городить два приложения QApplication (UI и логика) и QCoreAplication (обёртка COM), связанные между собой, например, по xml-rpc. (((
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #7 : Октябрь 22, 2014, 08:46 »

Пробовал, нет доступа. :-(
У меня объект существует ещё до создания потоков... и маршалить его ручками в поток не очень хочется...
Да, объекты должны создаваться в самом потоке после вызова инициализации.
А в чем проблема перенести его в отдельный поток. Можно сделать класс-враппер, куда спрятать всю работу с COM.
Записан
Dolu
Гость
« Ответ #8 : Октябрь 22, 2014, 09:02 »

Можно сделать класс-враппер, куда спрятать всю работу с COM.
Так и работаю

А в чем проблема перенести его в отдельный поток.
Есть такой вариант http://www.k-press.ru/cs/2000/4/com_htm/com_1.asp (параграф: "Клиентское приложение 2 – входим в многопоточный мир")
Есть ли материал как это сделать менее болезненно? Средствами Qt а не WinApi?
Записан
Johnik
Крякер
****
Offline Offline

Сообщений: 339


Просмотр профиля
« Ответ #9 : Октябрь 22, 2014, 09:06 »

Thread Support in Qt
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #10 : Октябрь 22, 2014, 09:12 »

Так и работаю
С отдельным потоком внутри? Я вам предлагаю сделать класс, который будет запускать отдельный поток, инициализировать COM, создавать там нужные объекты и их обслуживать.
Записан
Dolu
Гость
« Ответ #11 : Октябрь 22, 2014, 10:09 »

С отдельным потоком внутри? Я вам предлагаю сделать класс, который будет запускать отдельный поток, инициализировать COM, создавать там нужные объекты и их обслуживать.
Такой вариант мне не подходит, т.к. необходимо выполнять работу с COM параллельно (внутри COM обеспечена потокобезопасность)
Записан
Johnik
Крякер
****
Offline Offline

Сообщений: 339


Просмотр профиля
« Ответ #12 : Октябрь 22, 2014, 10:20 »

В потоке это и есть параллельно.

Второй вариант: попробуйте отключить DEP. Мне помогло.

Код:
bcdedit.exe /set {current} nx AlwaysOff
Подробнее, например, тут: http://netler.ru/ikt/windows7-dep.htm
Записан
Dolu
Гость
« Ответ #13 : Октябрь 22, 2014, 10:31 »

В потоке это и есть параллельно.
Имелось ввиду работа с одним COM в нескольких потоках конечно.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.099 секунд. Запросов: 23.