我有下一个情况:我需要在独立静态库中创建小部件,然后将其与最终应用程序(visual c 9.0,qt 4.5)进行链接.
此静态窗口小部件库包含一些资源(图标),并包含几个.cpp文件(每个都包含独立窗口小部件).据我所知,我必须初始化qt资源系统,如果我在静态库中使用它们(资源),调用“Q_INIT_RESOURCE(resource_file_name)”.我用下面的代码(静态库中的每个.cpp文件)解决了这个问题:
此静态窗口小部件库包含一些资源(图标),并包含几个.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文件中包含初始化代码),但这并不奏效.
为什么这不行?
StaticLibInitializer的这种方法在各种编译器和平台之间是否安全可移植?
解决方法
它没有工作,因为你设法得到打击
static initialization order fiasco.
您不能移动您的代码,以初始化静态对象超出翻译单位(您可以将其作为源文件读取)使用这些静态对象.不是你做的那样如果要使用您正在使用的方案来初始化这些静态对象,而不是仅将声明移动到init.hpp头,而是保留静态StaticLibInitializer staticLibInitializer;在每个使用静态对象的文件中.
以上建议假定每个小部件只使用自己的资源.如果你有一个小部件的资源被另一个小部件使用的情况,你将再次运行到静态初始化阶段fiasco.您可以使用这样的代码来管理这种情况
StaticLibInitializer { void initialize() { static Q_INIT_RESOURCE(qtwidgets_custom_resources); } StaticLibInitializer() { initialize(); } }
以确保StaticLibInitializer的乘法实例将初始化给定资源一次,然后为您将在给定的翻译单元中使用的每个资源实例化StaticLibInitializer.