【问题标题】:std::uncaught_exception does not work across DLL boundariesstd::uncaught_exception 不能跨 DLL 边界工作
【发布时间】:2016-11-15 19:57:41
【问题描述】:

我在 DLL 中有一个类,它带有一个检查 std::uncaught_exception() 的析构函数。如果在可执行文件中的 try/catch 块中使用,则如果抛出异常,则不会说 true。

下面是一些示例代码: lib.h:

#pragma once

class __declspec(dllexport) C final
{
  public:
    ~C();
};

lib.cpp:

#include "lib.h"
#include <iostream>
#include <exception>

C::~C()
{
  std::cout << "C says: Uncaught: " << (std::uncaught_exception() ? "yes" : "no") << std::endl;
}

main.cpp:

#include "lib.h"
#include <iostream>
#include <exception>

class D final
{
  public:
    ~D()
    {
      std::cout << "D says: Uncaught: " << (std::uncaught_exception() ? "yes" : "no") << std::endl;
    }
};


int main(int argc, char **argv)
{
  try
  {
    C c;
    D d;
    throw 88;
  }
  catch (int a)
  {
    std::cout << "Code: " << a << std::endl;
  }
  {
    C c;
    D d;
  }
  return 0;
}

并使用以下方法构建所有内容:

cl.exe lib.cpp /EHsc /LD /c /Fo:lib.obj
link.exe lib.obj /incremental:no /fixed:no /DLL
cl.exe main.cpp /EHsc /LD /c /Fo:main.obj
link.exe main.obj /incremental:no /fixed:no lib.lib

在 Visual Studio 2015 和 Visual Studio 2013 x64 和 x86 上,我得到了结果:

D says: Uncaught: yes
C says: Uncaught: no
Code: 88
D says: Uncaught: no
C says: Uncaught: no

我希望第二行是

C says: Uncaught: yes

因此,DLL 中的类看不到有异常导致堆栈展开,从而导致调用它的析构函数。但是直接位于内部类的类看到了。

是否有任何链接器/编译器标志可以使其按预期工作?

【问题讨论】:

  • 顺便说一句:在构建和使用库时区分 dllexport 和 dllimport 不会改变结果。
  • BTW2:与 std::uncaught_exceptions() 相同:在预期为 1 的地方给出 0。
  • 我的猜测是 dll 的运行时有它自己的一组返回 uncaught_exception 状态的标志。如果您将应用程序的 std::uncaught_exception 的函数指针传递到 dll 并改为调用该函数指针,也许您会得到预期的结果。
  • 原代码一年前已经在VS2013上运行,没有出现这个问题。那时我正在用 cmake 构建。现在我为 Windows 重新激活了该代码并直接构建调用 cl.exe 和 link.exe。

标签: c++ visual-c++ visual-studio-2013 visual-studio-2015


【解决方案1】:

使用/MD 动态运行时编译器选项。

没有一个,主可执行文件和每个 DLL 都有自己的运行时副本,每个模块的所有内部状态都复制。

【讨论】:

  • 请注意,不共享运行时可能会导致许多其他问题,不仅仅是这个!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-29
  • 1970-01-01
  • 2013-12-12
  • 1970-01-01
  • 1970-01-01
  • 2015-09-23
  • 2011-07-03
相关资源
最近更新 更多