Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.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
C++ 如何在共享库中调用atexit?_C++_Linux_Dlopen_Dlsym_Atexit - Fatal编程技术网

C++ 如何在共享库中调用atexit?

C++ 如何在共享库中调用atexit?,c++,linux,dlopen,dlsym,atexit,C++,Linux,Dlopen,Dlsym,Atexit,在共享库中,函数func1()具有atexit(terminate_global),而此共享库没有“属性((构造函数))”和“属性((析构函数))”。 因此,程序流程如下所示: 1)应用程序使用dlopen加载共享库。 2)应用程序使用dlsym调用func1()。 3)func1()具有atexit(terminate\u global)。 4)func1()返回。 5)应用程序调用dlclose取消分配库 在上述步骤中,我发现在卸载库时没有调用atexit()。那么,如果在取消分配共享库时必

在共享库中,函数func1()具有atexit(terminate_global),而此共享库没有“属性((构造函数))”和“属性((析构函数))”。
因此,程序流程如下所示:
1)应用程序使用dlopen加载共享库。
2)应用程序使用dlsym调用func1()。
3)func1()具有atexit(terminate\u global)。
4)func1()返回。
5)应用程序调用dlclose取消分配库


在上述步骤中,我发现在卸载库时没有调用atexit()。那么,如果在取消分配共享库时必须调用atexit(),那么正确的方法应该是什么呢?我是否应该使用属性((构造函数))和属性((析构函数))函数属性导出例程,以便调用atexit注册的函数?

我假设传递给
atexit
终止\u全局
函数是在插件中定义的。如果
terminate\u global
是一个由主程序定义的全局函数(与
-rdynamic
标志链接,以使其符号访问插件),那么插件可以调用
atexit(terminate\u global)
,但我会提供一些API函数来实现这一点

我不会这样做(在某个插件中调用
atexit(terminate\u-fun)
,其中
terminate\u-fun
是该插件定义的函数),除非您确信您的应用程序永远不会
dlclose
-ing该插件

如果您的应用程序在某个地方调用
dlclose
-在某个
atexit
-ing函数之外-那么
dlclose
很可能会
munmap
插件。因此当以后
exit
处理
atexit
时,它会崩溃(由于指向通过atexit注册的函数的指针无效且未映射)

你必须定义谁负责代码> dLCONCE/<代码>插件。如果你的应用程序明确地这样做,你可以通过代码< > AyAtEtTyth*((析构函数))< /Cult> C函数(或者插件中的一些静态C++数据的析构函数)来完成一些清理工作。,或定义并记录一个约定,例如,每个具有名为
plugin\u cleanup
的函数的插件(使用
dlsym
)都会适当调用该清除函数


否则,您可以定义并记录插件不是由您的应用程序显式地
dlclose
-d(这通常是可以的,特别是如果您提供一些清理机制的话)。但是,这可能会使
valgrind
不满意。

应用程序应该调用
atexit()
,而不是库。不要使事情过于复杂化。如果库需要清理,那么它应该只导出一些func,应用程序应该在退出时调用它。是什么用例让你想到了这一点?请编辑你的问题以激发它的积极性……atexit()处理程序在程序本身关闭时运行,而不是卸载库/插件时。为此,您需要向库中添加一个去初始化函数。大家好,非常感谢。我正在讨论的代码(或代码流)是我刚刚遇到的一些遗留代码。我将尝试使用一些去初始化或“\u属性”\u((析构函数))'以更正它。将使用工作解决方案更新回。根据glibc允许