Frage

Ich habe nächste Situation: Ich Widget in Standalone-statische Bibliothek erstellen müssen, die dann mit der endgültigen Anwendung verknüpft werden (Visual C ++ 9.0, qt 4.5). Diese statische Widget-Bibliothek enthält einige Ressourcen (Icons), und besteht aus einer mehrere CPP-Dateien (jedes enthält eigenständige Widget). Soweit ich weiß, muß ich qt Ressourcensystem initialisieren, wenn ich sie (Ressourcen) in statischer Bibliothek verwenden, mit Aufruf „Q_INIT_RESOURCE (resource_file_name)“. Ich löste dies mit dem nächsten Code (in jeder CPP-Datei in statischer Bibliothek):


#include <QAbstractButton>

namespace {
struct StaticLibInitializer
{
    StaticLibInitializer()
    {
        Q_INIT_RESOURCE(qtwidgets_custom_resources);
    }
};
StaticLibInitializer staticLibInitializer;
} 

// ... widget code ....

Statt meinem ersten Ansatz, ich habe in der statischen Bibliothek-Projekt mit Initialisierungscode separate init.cpp Datei erstellt (einschließlich Initialisierungscode in jeder CPP-Datei zu vermeiden), aber das hat nicht funktioniert.

Warum dies nicht funktioniert?

Ist dieser Ansatz mit StaticLibInitializer sicher und tragbar unter verschiedenen Compilern und Plattformen?

War es hilfreich?

Lösung

Es hat nicht funktioniert, weil Sie durch getroffen zu verwaltet statische Initialisierungsreihenfolge Fiasko .

Sie können Ihren Code nicht bewegen, die statischen Objekte, die Übersetzungseinheit überdimensional initialisiert (Sie es als Quelldatei lesen können), wo diese statischen Objekte verwendet werden. Nicht so, wie Sie haben es geschafft. Wenn Sie das Schema, das Sie verwenden verwenden möchten diese statische Objekte als Schachzug nur Erklärungen zu Ihrem init.hpp Header aber leave instatiations zu initialisieren StaticLibInitializer staticLibInitializer; in jeder Datei, die statische Objekte verwendet.
Above Beratung übernimmt jedes Widget verwendet nur seine eigenen Ressourcen. Wenn Sie Situation haben, in der ein Widget Ressourcen von einem anderen Widget verwendet werden, führen Sie in statische Initialisierungsreihenfolge wieder Fiasko. Sie können diese Situation verwalten, indem Code wie folgt mit

StaticLibInitializer
{
    void initialize()
    {
        static Q_INIT_RESOURCE(qtwidgets_custom_resources);
    }

    StaticLibInitializer()
    {
         initialize();
    }
}

, um sicherzustellen, mehrfach Instanzierungen StaticLibInitializer gegebene Ressource nur einmal initialisiert werden und dann instantiate StaticLibInitializer für jede Ressource, die Sie verwenden gehen in bestimmten Übersetzungseinheit.

Andere Tipps

Das Q_INIT_RESOURCE Makro kann nicht in einem Namespace verwendet werden.

Ich zitiere aus dem qt Handbuch: „Hinweis: Dieses Makro kann nicht in einem Namespace verwendet wird Es sollte von der Haupt () aufgerufen werden“. Und auch es gibt Ihnen ein Beispiel, wie man es richtig machen, wenn dies nicht möglich ist:

  inline void initMyResource() { Q_INIT_RESOURCE(myapp); }

    namespace MyNamespace
    {
     ...

     void myFunction()
     {
         initMyResource();
     }
  }

Bitte schauen Sie sich, warum und wie genau es ausfällt oder nicht scheitern, wenn Sie es in einer nicht spezifizierten Art und Weise nutzen. Der entsprechende Code ist in QtCore.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top