★ 问题现象:在析构函数中释放引用的 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)主动调用!