你是否正在處理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很好。 –