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 ?
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 .
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With