MFC异常情况
编译异常
情况一:编译DLL程序时,Debug导出函数正确;Release导出的函数不正确如下图所示
Debug:
Release:
1 | ?GetApplicationRecoveryParameter@CWinApp@@UAEPAXXZ (public: virtual void * __thiscall CWinApp::GetApplicationRecoveryParameter(void)) |
原因:编译器优化(Optimization)导致的符号别名(Symbol Aliasing) 问题;在开启优化(Release/Optimization On)时,MSVC 编译器发现这个函数的实现极其简单(可能只是直接返回了另一个函数的结果,或者函数体为空/仅包含跳转),于是它执行了“COMDAT 折叠”或“增量链接优化”,将这个函数的导出地址直接指向了它内部调用的那个 MFC 虚函数CWinApp::GetApplicationRecoveryParameter 的地址。
解决方法
方法一:去掉项目的的优化,如下图所示,禁止优化。
方法二:增加“volatile”副作用防止优化
可以在函数内部加入防止优化的代码,迫使编译器保留独立的函数体。
1 | extern "C" __declspec(dllexport) void* xxa() |
方法三:检查 .def 文件与 __declspec 的冲突
如果你同时使用了 .def 文件和 __declspec(dllexport),在某些优化级别下可能会产生冲突。
建议:如果使用 .def 文件导出,请移除代码中的 __declspec(dllexport),只保留普通的 extern “C” 声明。让链接器完全通过 .def 文件控制导出名称和顺序。
1 | extern "C" void* xxa(); // 不要加 __declspec(dllexport) |