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

时间:2015-10-23 17:10:01

标签: linux gcc destructor dlopen

我正在使用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。 感谢

1 个答案:

答案 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

我不知道使用该标志会产生什么其他后果。