dlclose () no funciona con la función de fábrica y la función estática compleja en la función?

Estoy creando un marco de plugin simple en el que me gustaría poder abrir una biblioteca compartida (es decir, un plugin), inspeccionar y usar las funciones de fábrica que se proporcionan y finalmente cerrar (), sin dejar rastro.

Mi sistema de fábrica es trivial, con una única función exportada que devuelve un puntero a una clase Base común. Para comprobar que el complemento se haya descargado correctamente, tengo un objeto estático cuyo destructor establece un bool del programa principal.

Aquí está el programa principal:

// 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;
}

Y el código del plugin es:

// 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; }

Si se ejecuta, la salida es:

false
false
~Finilizer()

Esto muestra que la llamada a dlclose () no funciona como se esperaba y que la biblioteca no se descargó hasta que se cerró el programa.

Sin embargo, si movemos el vector hacia afuera de la función, entonces las últimas 8 líneas leen:

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; }

Entonces dlclose () funciona correctamente y la salida es:

false
~Finilizer()
true

Se generan los mismos resultados si el vector se deja en la función pero no se exporta ninguna fábrica:

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; }

Se encuentran resultados positivos si el vector se sustituye con una matriz 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; }

¿Es este un error en GCC / Linux? ¿Hay alguna solución para que los objetos complejos puedan declararse estáticamente en una función miembro de una clase factorizada?

Respuestas a la pregunta(1)

Su respuesta a la pregunta