Я использую dlopen() и dlclose() для загрузки и выгрузки модуля. Модуль содержит некоторые статические данные, которые необходимо уничтожить при вызове dlclose(). Однако я обнаружил, что при определенных обстоятельствах dlclose() не вызывает деструкторы - вместо этого они вызывается только при выходе main().dlclose() статические деструкторы выполняются в разное время, если функция виртуальна
Я откинул свой код до этого. У меня есть класс, который содержит виртуальную функцию getType(), определенную внутри класса, ссылаясь на статические данные. У меня также есть объект StaticDestructionChecker, который просто печатает, когда вызываются статические конструкторы и деструкторы. Наконец у меня есть основная() функция, которая загружает все остальное через dlopen(), замыкает его через dlclose() и печатает, когда основные() закончено:
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(), чтобы быть невиртуальным ИЛИ если я удалить «статический Int T», деструкторы вызываются, когда ожидается, то есть выход:
Constructing static data
Destructing static data
end of main
Есть ли способ, чтобы получить правильный порядок уничтожения сохраняя при этом виртуальный/статический код? FYI - это упрощенная версия своего рода системы RTTI, где getType() автоматически создается с помощью макроса DECLARE_xxx, поэтому я не хочу переместить реализацию в файл cpp, потому что потребуется второй вызов макроса там тоже. Я использую GCC 4.8 на Ubuntu 12. Благодаря