Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何处理第三方库代码中的exit()调用? 我正在研究C++应用程序,它使用另一个团队用C编写的库。当错误发生时,库的作者喜欢调用退出()/>代码,这就立即结束了程序,而不调用C++应用程序中堆栈上对象的析构函数。应用程序设置了一些在进程结束后不会被操作系统自动回收的系统资源(共享内存区域、进程间互斥体等),因此这是一个问题_C++_Legacy Code - Fatal编程技术网

如何处理第三方库代码中的exit()调用? 我正在研究C++应用程序,它使用另一个团队用C编写的库。当错误发生时,库的作者喜欢调用退出()/>代码,这就立即结束了程序,而不调用C++应用程序中堆栈上对象的析构函数。应用程序设置了一些在进程结束后不会被操作系统自动回收的系统资源(共享内存区域、进程间互斥体等),因此这是一个问题

如何处理第三方库代码中的exit()调用? 我正在研究C++应用程序,它使用另一个团队用C编写的库。当错误发生时,库的作者喜欢调用退出()/>代码,这就立即结束了程序,而不调用C++应用程序中堆栈上对象的析构函数。应用程序设置了一些在进程结束后不会被操作系统自动回收的系统资源(共享内存区域、进程间互斥体等),因此这是一个问题,c++,legacy-code,C++,Legacy Code,我有完整的应用程序和库的源代码,但是库是非常完善的,没有单元测试,所以更改它将是一件大事。有没有办法“钩住”调用exit(),这样我就可以实现应用程序的正常关机 我正在考虑的一种可能性是生成一个大类,即应用程序,这意味着所有清理都将发生在其析构函数中或其成员的析构函数中,然后在main()中的堆上分配这些大对象中的一个,设置指向它的全局指针,并使用atexit()注册处理程序,该处理程序仅通过全局指针删除对象。这可能有效吗 是否有一种已知的解决此问题的好方法?在最坏的情况下,您始终可以编写自己的

我有完整的应用程序和库的源代码,但是库是非常完善的,没有单元测试,所以更改它将是一件大事。有没有办法“钩住”调用
exit()
,这样我就可以实现应用程序的正常关机

我正在考虑的一种可能性是生成一个大类,即应用程序,这意味着所有清理都将发生在其析构函数中或其成员的析构函数中,然后在
main()
中的堆上分配这些大对象中的一个,设置指向它的全局指针,并使用
atexit()
注册处理程序,该处理程序仅通过全局指针删除对象。这可能有效吗


是否有一种已知的解决此问题的好方法?

在最坏的情况下,您始终可以编写自己的
exit
实现并链接它,而不是系统自己的实现。您可以在那里处理错误,也可以选择调用您自己


因为拥有库源,更容易-只需在构建时添加一个<代码> -DEXIT= MyExt/<代码>标志,然后提供一个实现,代码<> MyExeX .< /P> < P>安装退出处理程序,并实现所需的行为

,如果您想使C++库更易于从C++中使用,您也许可以在单独的进程中运行它。然后确保(使用退出处理程序或其他方式)当它退出时,您的主应用程序进程会注意到并抛出一个异常以释放它自己的堆栈。也许在某些情况下,它可以以非致命的方式处理错误

当然,将库的使用转移到另一个过程可能并不容易,也不是特别有效。您需要做一些工作来包装接口,并通过您选择的IPC机制复制输入和输出

不过,作为从主流程使用库的一种变通方法,我认为您描述的方法应该有效。风险在于您无法识别和隔离所有需要清理的内容,或者将来有人会在堆栈正常展开的前提下修改您的应用程序(或您使用的另一个组件)


您可以修改库源以调用运行时或编译时可配置函数,而不是调用
exit()
。通过异常处理编译库,实现C++中的函数抛出异常。这样做的问题是库本身可能会在出错时泄漏资源,因此您只能使用该异常来展开堆栈(并可能执行一些错误报告)。即使对于你的应用程序而言,错误可能不是致命的,也不要捕捉它并继续。如果呼叫
退出
,而不是
断言
中止
,则有几点需要再次控制:

  • 调用
    exit
    时,具有静态生存期的对象(基本上是:全局对象和使用
    static
    声明的对象)的析构函数仍在执行。这意味着您可以设置(几个)全局“资源管理器”对象,并在其析构函数中释放资源
  • 正如您已经发现的,您可以使用
    atexit
    注册挂钩。这不限于一个。你可以注册更多

如果所有其他操作都失败了,因为您拥有库的源代码,您可以使用一些宏技巧,用您自己的函数(例如,可以抛出异常)有效地替换对
exit
的调用。

我确实想到了这一点(这是个问题)。问题是调用堆栈上每个函数中的局部变量对于一个简单的处理程序来说都是不可用的——因此我想让应用程序本身成为一个在堆上分配的单个对象,并通过一个全局指针来删除。啊哈!在编译C库时,C++应用程序的Mag文件可以重新定义<代码>出口>代码> -根本不需要修改代码。我仍然需要实现从全局处理程序清理整个应用程序的功能,但这仍然是迄今为止最好的答案。嘿,我现在正试图在linux机器上使用
-Dexit=myExit
,但不幸的是,我遇到了这个错误:
在/usr/include/c++/7/ext/string\u conversions.h:41:0包含的文件中,from/usr/include/c++/7/bits/basic_string.h:6352,from/usr/include/c++/7/string:52…/usr/include/c++/7/cstdlib:146:11:错误:“::exit”未使用::exit声明您对修复有什么想法吗?张贴于: