★ 問題現象:在析構函數中釋放引用的 COM 指針,導致異常。
1、總是在一個固定地址報告異常。該地址的匯編碼在程序退出前可見(有效),在異常出現時不可見(全為問號)。
2、設置斷點后發現,調試器無法計算該指針表達式的值;
3、在內存窗口中查看該指針指向的內容,發現可視范圍內全是問號(不可訪問)
★ 原因、查找過程
1、在欲釋放的指針所在的dll卸載的地方(CXxxxApp::ExitInstance())設上斷點,發現它在出錯代碼前就執行了!
2、因為出錯代碼處也是一個dll模塊內,而且和出錯指針對象所在的dll不是一個。據此,判斷應該是,主模塊(exe)在卸載dll時,先卸載了指針所在的dll(而且報了內存泄露),再卸載出錯代碼所在的dll,由于此時指針所在的模塊已經釋放,故內存失效!
★ 解決辦法
1、對于dll模塊的代碼,絕對不要在析構函數或模塊退出時訪問另一個dll的內容!因為 dll 的卸載順序是不可靠或很難管理的!(exe卸載的順序是可靠的,exe必定是最后卸載)
2、如果要在結束時釋放某些東西,應該為 dll 導出一個類似‘Uninitialize()’的函數,由主模塊(exe)主動調用!