Cannot create a win event notifier without a QEventDispatcherWin32問題解決個人整理
最近因為工作上的需要,對系統在架構上進行解耦,參考之前做的東西考慮對進程間通信封裝一個動態庫,不同的進程加載動態庫提供的通用接口來進行消息收發。正好在學習qt,於是基於qt的qlocalserver來進行了動態庫的開發。開發完成之後,問題來了。。。有一部分功能是使用網頁來展現的,我們用了一個公司買的封裝過的瀏覽器來加載網頁,網頁的事件由瀏覽器加載的np插件來響應,我的思路就是我用開發的np插件(這也是一個動態庫)加載我的動態庫,來實現np插件與我的服務進程之間的通信。開發都很順利。。。編譯,使用dependence查看動態庫是否有依賴缺失,顯示也很正常,但是瀏覽器加載np插件的時候就插件就崩潰了,報出這樣的錯誤:Cannot create a win event notifier without a QEventDispatcherWin32。
百度之,答案是這樣的:https://stackoverflow.com/questions/3511044/cannot-create-a-win-event-notifier-without-a-qeventdispatcherwin32。
這人說他是用release版本的應用調用了debug版本的動態庫。因為我的都是用的debug版本的,所以顯然不是這個錯誤了。
繼續百度,相關的幾乎沒有,回到調試的工程,發現是在初始化一個qlocalsocket對象的時候崩潰的,往下調試的話會發現在報錯是出現在這個文件qwineventnotifier_p.cpp的這句話
QEventDispatcherWin32 *eventDispatcher = qobject_cast<QEventDispatcherWin32 *>(d->threadData->eventDispatcher);
這個d->threadData->eventDispatcher在內存中調看是空的。哎。對qt我也是初學者,老老實實地再去google一下吧。(真的感覺百度不好用,特別是這種偏門的錯誤,百度幾乎沒有。之前做過一個qt的文件樹也是百度啥也搜不到,這個準備另寫一篇)也搜了bing,結果前三條都是跟上面一樣的,但是還是有一條引起了我的註意:
http://www.qtcentre.org/archive/index.php/t-43522.html
這裏面作者列舉了一個在啟動QCoreApplication a(argc,argv)之前訪問QObject引起錯誤的實例。當然後面亂七八糟的回復也沒人說解決了這個問題。但是這給了我一個思路,因為np插件是c++寫的,加載np插件的plugins-container.exe顯然也不是qt寫的,而我之前調試的時候都是使用qt進程進行的。因此我立即寫了一個簡單的c++win32控制臺程序來加載我的插件,果然出現了上面的錯誤。
問題找到了,顯然qt的一些類(基於QObject)是需要基於一個QCoreApplication的實例化對象的,這樣再去搜索找到這樣一個答案:https://stackoverflow.com/questions/2150488/using-a-qt-based-dll-in-a-non-qt-application。
參照答主自己的描述(他自己提供了一個解決方法),因為我們整個動態庫的主線程使用了qlocalserver,所以我在插件的入口加上這樣的代碼:
QCoreApplication *_pQCoreApplication; if (QCoreApplication::instance() == NULL) {
//如果不是qt進程 則自己實例化一個QCoreApplication int argc = 1; char* argv[] = { "dummy.exe", NULL };//進程名可以隨便起一個 無所謂的 _pQCoreApplication = new QCoreApplication(argc, argv); _pQCoreApplication.processEvents(); } else { _pQCoreApplication = NULL; }
問題是解決了,進程運行也正常了,無論是內存還是析構都沒有報出異常,但是問題和提問者是一樣的,就是這樣使用是否安全,以及是否合適,還有待思考和查詢。
待續。
Cannot create a win event notifier without a QEventDispatcherWin32問題解決個人整理