你是否正在处理DLL中的所有异常?如果任何异常使用C调用约定在函数外部“泄漏”,则会使应用程序崩溃。
我有C++异常下MinGW的x86_64-5.3.0-Win32的SEH-rt_v4-REV0和没有问题的mingw32 4.8.1 DWARF2具有静态的libstdC++/libgcc中。
DLL源(dll.cpp
):
#include <windows.h>
#include <exception>
#include <iostream>
extern "C" {
__declspec(dllexport) int __stdcall test() {
try {
new int[-1];
return 123;
} catch (const std::exception& ex) {
std::cerr << "Exception:" << ex.what() << std::endl;
return 456;
}
}
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
return TRUE;
}
应用源(app.c
):
#include <stdio.h>
#ifdef __cplusplus
extern "C"
#endif
__declspec(dllimport) int __stdcall test();
int main() {
printf("result: %d\n", test());
return 0;
}
编译:
g++ -O2 -static-libgcc -static-libstdc++ -shared -Wl,--out-implib=dtest.lib -s -o dtest.dll dll.cpp
g++ -O2 -static-libgcc -static-libstdc++ -L. -s -o app app.c -ldtest
输出:
Exception:std::bad_alloc
result: 456
为了回答您的评论“为什么我需要SEH支持的编译器?我认为SEH允许我捕捉Windows例外“ - 在Windows上,SEH是的所有例外的事实标准,包括C++异常(当使用Visual C++编译时)MinGW对于C++异常有不同的实现(SEH,SJLJ和DWARF),但是SEH是唯一没有开销的机制,所以如果它可用,你应该更喜欢它通过SJLJ和DWARF。
使用TDM-GCC。请参阅[简介](http://tdm-gcc.tdragon.net/quirks) – Ripi2
或MinGW,它支持SEH。 – rustyx
@RustyX OP已经尝试了MinGW,正如你所说的那样支持SEH,但是如果库是静态链接的并且异常是通过DLL边界引发的,那么不会。这是TDM-GCC解决的问题之一。如果运行时库是动态链接的(即在进程中只有一个版本),MinGW很好。 –