Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initializing qt resources embedded in static library

I have next situation: I need to create widget in standalone static library, which then will be linked with final application (visual c++ 9.0, qt 4.5). This static widget library contains some resources (icons), and consist of a several .cpp files (each contains standalone widget). As far as I know, i must initialize qt resource system, if i use them (resources) in static library, with call to "Q_INIT_RESOURCE( resource_file_name )". I solved this with next code (in every .cpp file in static library):


#include <QAbstractButton>

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

// ... widget code ....

Instead of my first approach, I have created separate init.cpp file in static library project with initialization code (to avoid including initialization code in every .cpp file), but this didn't work.

Why this didn't work ?

Is this approach with StaticLibInitializer is safe and portable among various compilers and platforms ?

like image 725
cybevnm Avatar asked Sep 08 '09 09:09

cybevnm


People also ask

What is QRC file in Qt?

Qt Resource Collection File (. qrc file is an XML document that enumerates local files to be included as runtime resources. It serves as input to rcc .

What is RCC in Qt?

The rcc tool is used to embed resources into a Qt application during the build process. It works by generating a C++ source file containing data specified in a Qt resource (. qrc) file.


1 Answers

It didn't work because you managed to get hit by static initialization order fiasco.

You can't move your code that initializes static objects outsize the translation unit (you can read it as source file) where these static objects are used. Not the way you did it. If you want to use the scheme you are using to initialize these static objects than move only declarations to your init.hpp header but leave instatiations StaticLibInitializer staticLibInitializer; in each file which uses static objects.
Above advice assumes each widget uses only its own resources. If you have situation in which one widget's resources are used by another widget you run into static initialization order fiasco again. You can manage this situation by using code like this

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

    StaticLibInitializer()
    {
         initialize();
    }
}

to make sure multiply instantiations of StaticLibInitializer will initialize given resource only once and then instantiate StaticLibInitializer for every resource you are going to use in given translation unit.

like image 74
Piotr Dobrogost Avatar answered Sep 20 '22 12:09

Piotr Dobrogost