std::set_terminate for DLL?

std::set_terminate for DLL?

本文关键字:DLL for set std terminate      更新时间:2023-10-16

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

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

如果我负责应用程序的代码,我将在main()内使用std :: set_terminate来设置catch-All错误处理功能。但是由于我的DLL将在其他人的应用程序中

我有没有办法创建这样的替代,只能应用我自己的代码,而无需做一些令人讨厌的事情,例如在try/catch Block或其他应用程序中使用我的每个应用程序的功能?

设计dll时,应确保永远不要让异常从入口点逃脱。跨模块边界会变得棘手的例外,如果它们完全工作,并且最好避免它们。

引用 C 编码标准:Herb Sutter和Andrei Alexandrescu的101条规则,准则和最佳实践

项目62:不允许异常在模块边界传播。

不要将石头扔进邻居的花园:C 异常处理没有无处不在的二进制标准。除非您控制用于构建双方的编译器和编译器选项,否则不要允许异常在两个代码之间传播。否则,模块可能不支持异常传播的兼容实现。通常,这归结为:不要让异常在模块/子系统边界传播。

当您处理DLL(而不是静态库)时,您没有任何保证。消耗DLL的第三方应用程序是外国模块(邻居的花园)。您不能保证将使用相同的编译器和编译器选项编译两个模块,因此您不知道它们是否会以相同的方式对待异常。实际上,您甚至都不知道两个模块是否都会用C 编写,因此让C 例外传播是正确的。您可以通过Windows的结构化异常处理(SEH)成功地在模块边界上成功传播异常,但是您不应该。

除了技术和实施问题之外,从DLL引发例外只是产生了一个不良的界面。客户端应用程序不必从您的DLL例程中处理异常。例外是实现详细信息:您应该在内部处理它们。如果您需要指示成功或失败,请返回错误代码。这些可以通过的语言来处理您的DLL,从C到Basic到Python。

您提出的解决方案基本上是连接一个全局,未经处理的异常处理程序,该处理程序会在之前抓住您的dll 抛出的所有异常,它们越过模块边界。那不是真的。DLL没有全球异常处理程序。例外通过放松(上升)呼叫堆栈来传播,直到找到合适的处理程序。如果没有处理程序,他们将一直传播到入口点(main),如果在那里处理,它们将导致申请终止,并且操作系统将呈现"友好"。对话。这就是为什么在应用程序中很容易安装一个未经处理的异常处理程序的原因。DLL没有这样的等效物,因为DLL没有其自己的单个中央main函数。取而代之的是,它具有一系列输入点:由客户端应用程序调用的导出功能。因此,您未手持的异常处理程序应该在那些入口点中。

每个入口处都有其自己的异常处理程序。如果需要,您基本上可以将整个入口点包裹在大试用点中。这样,您所有的内部实施功能都可以在鲁ck放弃的情况下抛出异常,但是它们都会被捕获到入口点之前,然后才能在模块外传播。

将DLL提供的每个入口点(导出功能)作为其自己的main函数,因为这基本上就是它。DllMain函数(如Windows在Windows上常见的那样)是完全不同的。您在允许在那里做的事情非常有限

作为另一个点,您可能不想在DLL中的代码中调用abortstd::terminate,因为这将终止整个过程,包括客户端应用程序。当您是别人家中的客人时,您不应该致电拆除公司将房屋摧毁。在内部记录您的异常,但要尽一切努力维持一致的外部状态,而不是因为您遇到了内部错误,

崩溃。