2015-10-23 9 views
0

Я использую 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. Благодаря

ответ

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 

я не знаю каковы другие последствия использования этого флага.