Инициализация ресурсов qt, встроенных в статическую библиотеку

У меня следующая ситуация: мне нужно создать виджет в Автономной статической библиотеке, который затем будет связан с конечным приложением (visual c++ 9.0, qt 4.5). Эта статическая библиотека виджетов содержит некоторые ресурсы (значки) и состоит из нескольких .cpp файлы (каждый содержит автономный виджет). Насколько я знаю, я должен Инициализировать систему ресурсов qt, если я использую их( ресурсы) в статической библиотеке, с вызовом "Q_INIT_RESOURCE (resource_file_name )". Я решил это со следующим кодом (в каждом .файл cpp в статической библиотеке):


#include <QAbstractButton>

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

// ... widget code ....

вместо моего первого подхода я создал отдельный init.cpp-файл в проекте статической библиотеки с кодом инициализации (чтобы избежать включения кода инициализации в каждый.cpp file), но это не сработало.

почему это не работает ?

является ли этот подход с StaticLibInitializer безопасным и портативным среди различных компиляторов и платформ ?

2 ответов


это не сработало, потому что вам удалось попасть статическая инициализация заказ фиаско.

вы не можете переместить код, который инициализирует статические объекты, в единицу перевода (вы можете прочитать его как исходный файл), где используются эти статические объекты. Не так, как ты. Если вы хотите использовать схему, используемую для инициализации этих статических объектов, переместите только объявления в init.заголовок hpp, но оставьте instatiations StaticLibInitializer staticLibInitializer; в каждом файле, который использует статический объект.
Выше совет предполагает, что каждый виджет использует только свои собственные ресурсы. Если у вас есть ситуация, в которой ресурсы одного виджета используются другим виджетом, вы снова сталкиваетесь со статическим фиаско порядка инициализации. Вы можете управлять этой ситуацией, используя такой код

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

    StaticLibInitializer()
    {
         initialize();
    }
}

чтобы убедиться, что многократные экземпляры StaticLibInitializer инициализируют данный ресурс только один раз, а затем создают экземпляр StaticLibInitializer для каждого ресурса, который вы собираетесь использовать в данном единица перевода.


макрос Q_INIT_RESOURCE нельзя использовать в пространстве имен.

позвольте мне процитировать из руководства qt: "Примечание: этот макрос нельзя использовать в пространстве имен. Он должен быть вызван из main()". И даже это дает вам пример, как это сделать правильно, если это невозможно:

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

    namespace MyNamespace
    {
     ...

     void myFunction()
     {
         initMyResource();
     }
  }

пожалуйста, посмотрите сами, почему и как именно он терпит неудачу или не терпит неудачу, если вы используете его неопределенным образом. Соответствующий код находится в QtCore.