gpt4 book ai didi

c++ - DLL 的 std::set_terminate?

转载 作者:搜寻专家 更新时间:2023-10-31 00:25:45 24 4
gpt4 key购买 nike

我有一个将由另一个第 3 方应用程序加载的 DLL。

我正在尝试弄清楚是否有可能捕获由我自己的 DLL 生成的任何/所有异常。

如果我负责应用程序的代码,我会在 main() 中使用 std::set_terminate 来设置一个包罗万象的错误处理函数。但是因为我的 DLL 将在其他人的应用程序中,所以我不能在 main() 中调用 std::set_terminate。

有没有办法让我创建这样一个只应用我自己的代码的覆盖,而不用做一些令人讨厌的事情,比如将我的应用程序的每一个函数都放在 try/catch block 或其他东西中?

最佳答案

在设计 DLL 时,您应该确保永远不要让异常从您的入口点逃逸。跨模块边界的异常会变得很棘手,如果它们有效的话,你最好避免它们。

引自 Herb Sutter 和 Andrei Alexandrescu 的 C++ 编码标准:101 条规则、指南和最佳实践:

Item 62: Don't allow exceptions to propagate across module boundaries.

Don't throw stones into your neighbor's garden: There is no ubiquitous binary standard for C++ exception handling. Don't allow exceptions to propagate between two pieces of code unless you control the compiler and compiler options used to build both sides; otherwise, the modules might not support compatible implementations for exception propagation. Typically, this boils down to: Don't let exceptions propagate across module/subsystem boundaries.

当您处理 DLL 而不是静态库时,您没有任何保证。使用你的 DLL 的第三方应用程序是一个外部模块(邻居的花园)。您无法保证这两个模块将使用相同的编译器和编译器选项进行编译,因此您不知道它们是否会以相同的方式处理异常。事实上,您甚至不知道这两个模块是否将用 C++ 编写,因此让 C++ 异常传播是正确的。使用 Windows 的结构化异常处理 (SEH),您可以通过多种方式成功跨模块边界传播异常,但您不应该这么做。

但是,除了技术和实现问题之外,从 DLL 中抛出异常只会创建一个错误的接口(interface)。客户端应用程序不必处理来自 DLL 例程的异常。异常(exception)是实现细节:您应该在内部处理它们。如果需要指示成功或失败,则返回错误代码。这些可以通过任何可能使用您的 DLL 的语言轻松处理,从 C 到 BASIC 再到 Python。

您建议的解决方案基本上是连接一个全局的、未处理的异常处理程序,该处理程序将在您的 DLL 跨越模块边界之前捕获所有异常。那真的不存在。 DLL 没有全局异常处理程序。异常通过展开(向上移动)调用堆栈来传播,直到它们找到合适的处理程序。如果没有处理程序,它们将一直传播到入口点 (main),如果不在那里处理,它们将导致应用程序终止,并且操作系统将显示一个“友好”对话。这就是为什么很容易在应用程序 中安装未处理的异常处理程序的原因。 DLL 没有这样的等价物,因为 DLL 没有自己单一的中央 main 函数。相反,它具有一系列入口点:由客户端应用程序调用的导出函数。因此,您未处理的异常处理程序应该在这些入口点中。

每个入口点都有自己的异常处理程序。如果需要,您基本上可以将整个入口点包装在一个大的 try-catch 中。这样,您所有的内部实现函数都可以不计后果地抛出异常,但在它们被允许传播到模块外部之前,它们都会被困在入口点中。

将您的 DLL 提供的每个入口点(导出的函数)视为它自己的 main 函数,因为它基本上就是这样。 DllMain 函数(在 Windows 上通常为人所知)完全不同。就允许您在那里执行的操作而言,您受到如此严格的限制,因此您永远不应该调用可能引发异常的代码。

另外一点,您可能不希望从 DLL 中的代码调用 abortstd::terminate,因为那样会终止 整个过程,包括客户端应用程序。 When you're a guest in someone else's house , you shouldn't call the demolition company to have their house destroyed .在内部记录您的异常,但尽一切努力保持一致的外部状态,不会仅仅因为遇到内部错误而使客户端应用程序崩溃。

关于c++ - DLL 的 std::set_terminate?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55054744/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com