gpt4 book ai didi

linux - 如果函数是虚拟的,dlclose() 静态析构函数在不同时间运行

转载 作者:太空宇宙 更新时间:2023-11-04 13:03:30 25 4
gpt4 key购买 nike

我正在使用 dlopen() 和 dlclose() 加载和卸载模块。该模块包含一些需要在调用 dlclose() 时销毁的静态数据。然而,我发现在某些情况下,dlclose() 不会调用析构函数 - 相反,它们只会在 main() 退出时调用。

我已经将我的代码归结为这个。我有一个类,其中包含在类内部定义的虚函数 getType(),引用静态数据。我还有一个 StaticDestructionChecker 对象,它只在调用静态构造函数和析构函数时打印。最后我有一个 main() 函数,它通过 dlopen() 加载其他所有内容,通过 dlclose() 关闭它并在 main() 完成时打印:

模块1.h

#ifndef MODULE1_H
#define MODULE1_H

class MyClass
{
public:
MyClass();
virtual ~MyClass();

virtual int& getType() const
{
static int t(123);
return t;
}
};
#endif // MODULE1_H

模块1.cpp

#include <stdio.h>
#include "module1.h"

MyClass::MyClass()
{
}

MyClass::~MyClass()
{
}

class StaticDestructionChecker
{
public:
StaticDestructionChecker()
{
printf("Constructing static data\n");
}
~StaticDestructionChecker()
{
printf("Destructing static data\n");
}
};

StaticDestructionChecker checker;

主要内容:

#include <dlfcn.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
void* handle = dlopen("module1.so", RTLD_NOW);
if (!handle) printf("dlopen error: %s\n", dlerror());
dlclose(handle);
printf("end of main\n");
return 0;
}

按原样运行所有这些会导致静态数据在 main 终止后被破坏,即输出为:

Constructing static data
end of main
Destructing static data

问题出在 getType() 中的虚拟/静态组合。如果我将 getType() 更改为非虚拟的,或者如果我删除“static int t”,析构函数将在预期时被调用,即输出为:

Constructing static data
Destructing static data
end of main

有没有办法在保持虚拟/静态代码的同时获得正确的销毁顺序?仅供引用,这是一种自定义 RTTI 系统的简化版本,其中 getType() 是通过 DECLARE_xxx 宏自动生成的,所以我不想将实现移到 cpp 文件中,因为需要进行第二个宏调用也在那里。我在 Ubuntu 12 上使用 GCC 4.8。谢谢

最佳答案

参见 dlclose() doesn't work with factory function & complex static in function?

如果您使用 gold 链接器而不是在链接 module1.so 时传递 --no-gnu-unique 标志可以解决问题:

]$ g++ -o module1.so -shared -fPIC -Wl,--no-gnu-unique module1.cpp
]$ g++ main.cpp -ldl
]$ LD_LIBRARY_PATH=. ./a.out
Constructing static data
Destructing static data
end of main

我不知道使用该标志的其他后果是什么。

关于linux - 如果函数是虚拟的,dlclose() 静态析构函数在不同时间运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33307932/

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