我正在使用dlopen()和dlclose()来加载和卸载模块。该模块包含一些需要在调用dlclose()时被破坏的静态数据。但是我发现在某些情况下dlclose()不会调用析构函数 - 而只是在main()退出时调用它们。
我把我的代码煮到了这个。我有一个类,它包含在类中定义的虚函数getType(),引用静态数据。我还有一个StaticDestructionChecker对象,它只在调用静态构造函数和析构函数时打印。最后我有一个main()函数,通过dlopen()加载其他所有内容,通过dlclose()关闭它,并在main()完成时打印:
module1.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
module1.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;
}
按原样运行所有这些会导致静态数据在主终止后被破坏,即输出为:
Constructing static data
end of main
Destructing static data
问题在于getType()中的虚拟/静态组合。如果我将getType()更改为非虚拟OR,如果我删除“static int t”,则会在预期时调用析构函数,即输出为:
Constructing static data
Destructing static data
end of main
有没有办法在保持虚拟/静态代码的同时获得正确的销毁订单?仅供参考这是一种自定义RTTI系统的简化版本,其中getType()是通过DECLARE_xxx宏自动生成的,所以我不想将实现移动到cpp文件中,因为需要进行第二次宏调用在那里。 我在Ubuntu 12上使用GCC 4.8。 感谢
答案 0 :(得分:0)
请参阅dlclose() doesn't work with factory function & complex static in function?
如果使用gold
链接器而不是在链接--no-gnu-unique
时传递module1.so
标志,则修复问题:
]$ 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
我不知道使用该标志会产生什么其他后果。