dlclose () nie działa z funkcją fabryczną i złożoną funkcją statyczną?

Tworzę prostą strukturę wtyczek, w której chciałbym być w stanie dlopen () udostępnioną bibliotekę (tj. Wtyczkę), sprawdzać i używać dowolnych funkcji fabrycznych, jakie zapewnia i ewentualnie dlclose (), nie pozostawiając śladu.

Mój system fabryczny jest trywialny, z jedną eksportowaną funkcją, która zwraca wskaźnik do wspólnej klasy bazowej. Aby sprawdzić, czy wtyczka została poprawnie wyładowana, mam obiekt statyczny, którego destruktor ustawia bool z programu głównego.

Oto główny program:

// dltest.cpp follows. Compile with g++ -std=c++0x dltest.cpp -o dltest -ldl
#include <dlfcn.h>
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
    if (argc > 1)
    {
        void* h = dlopen(argv[1], RTLD_NOW|RTLD_LOCAL);
        if (!h)
        {
            cerr << "ERROR: " << dlerror() << endl;
            return 1;
        }
        bool isFinilized = false;
        *(bool**)dlsym(h, "g_finilized") = &isFinilized;
        cout << boolalpha << isFinilized << endl;
        if (dlclose(h))
        {
            cerr << "ERROR: " << dlerror() << endl;
            return 2;
        }
        cout << boolalpha << isFinilized << endl;
    }
    return 0;
}

Kod wtyczki to:

// libempty.cpp follows. Compile with g++ -std=c++0x libempty.cpp -o libempty.so -fPIC -shared
#include <iostream>
#include <vector>
using namespace std;
bool* g_finilized = nullptr;
struct Finilizer
{
    ~Finilizer()
    {
        cout << "~Finilizer()" << endl;
        if (g_finilized) *g_finilized = true;
    }
} g_finilizer;
class Base
{
public:
    virtual void init() = 0;
};
class Foo: public Base
{
    virtual void init()
    {
        static const vector<float> ns = { 0.f, 0.75f, 0.67f, 0.87f };
    }
};
extern "C" __attribute__ ((visibility ("default"))) Base* newBase() { return new Foo; }

Jeśli zostanie wykonane, dane wyjściowe to:

false
false
~Finilizer()

To pokazuje, że wywołanie dlclose () nie działa zgodnie z oczekiwaniami i biblioteka nie została zwolniona do czasu zakończenia programu.

Jeśli jednak przeniesiemy wektor na zewnątrz funkcji, ostatnie 8 linii będzie czytać:

class Foo: public Base
{
    virtual void init()
    {
    }
};
static const vector<float> ns = { 0.f, 0.75f, 0.67f, 0.87f };
extern "C" __attribute__ ((visibility ("default"))) Base* newBase() { return new Foo; }

Następnie dlclose () działa poprawnie, a dane wyjściowe to:

false
~Finilizer()
true

Te same wyniki są generowane, jeśli wektor pozostanie w funkcji, ale żadna fabryka nie zostanie wyeksportowana:

class Foo: public Base
{
    virtual void init()
    {
        static const vector<float> ns = { 0.f, 0.75f, 0.67f, 0.87f };
    }
};
//extern "C" __attribute__ ((visibility ("default"))) Base* newBase() { return new Foo; }

Pozytywne wyniki można znaleźć, jeśli wektor zostanie zastąpiony tablicą C:

class Foo: public Base
{
    virtual void init()
    {
        static const float ns[] = { 0.f, 0.75f, 0.67f, 0.87f };
    }
};
extern "C" __attribute__ ((visibility ("default"))) Base* newBase() { return new Foo; }

Czy to błąd w GCC / Linux? Czy jest jakieś obejście problemu, aby obiekty złożone mogły być deklarowane statycznie w funkcji składowej klasy z faktoryzacją?

questionAnswers(1)

yourAnswerToTheQuestion