c++ - Windows DLL 上的静态链接 libgcc

标签 c++ windows dll exception

我正在用 C++ 编写一个 Windows DLL。该库只有 C 接口(interface),并且仅使用也有 C 接口(interface)的标准 Windows 库。因此,将所有 C++ 库静态链接到库中似乎是安全的,因为仅使用 C 接口(interface)时,我不依赖于 C++ ABI 版本。

不幸的是,当我使用 -static-stdc++ -static-libgcc 编译库时,我的库停止处理异常,并且当引发某些异常时,DLL 调用其静态链接的 _Unwind_RaiseException 中止整个应用程序的函数。

我认为它可能是一个损坏的libgtcc.a,所以我尝试更新我的编译器。但 MinGW 4.8 和 MinGW 6.3 的结果是相同的。

请问有人可以向我解释一下这里到底发生了什么吗?

克拉西克

最佳答案

您是否处理了 DLL 内的所有异常?如果任何异常“泄漏”到具有 C 调用约定的函数之外,就会导致应用程序崩溃。

在使用静态 libstdc++ 的 MinGW x86_64-5.3.0-win32-seh-rt_v4-rev0mingw32 4.8.1 dwarf2 下,我对 C++ 异常没有任何问题/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。

关于c++ - Windows DLL 上的静态链接 libgcc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42159583/

相关文章:

c++ - 在 Windows 环境下在 PostgreSQL 9.1 中创建函数

c++ - 微软对 std::regex 的实现

c++ - 使用 GCC 扩展定义

c++ - 如何修复 xcode 词法或预处理器问题,在 xcode 6.3 中找不到数组文件?

c++ - 如何执行快速用户切换

java - 重新启动 linux 和 windows 的 java 应用程序

windows - 测量 UNC 路径访问时间的工具

c# - 我可以在非托管 Delphi EXE 中使用托管 C# DLL 吗?

c++ - CGAL:错误的 Delaunay 结果?

c# - 在 C# winforms 中使用 C++ 库