我有下一种情况:我需要在独立静态库中创建小部件,然后将其与最终应用程序(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 文件中包含初始化代码),但这不起作用。
为什么这不起作用?
这种使用 StaticLibInitializer 的方法在各种编译器和平台之间是否安全且可移植?
它不起作用,因为你设法被击中静态初始化顺序惨败 https://isocpp.org/wiki/faq/ctors#static-init-order.
您不能将初始化静态对象的代码移动到使用这些静态对象的翻译单元(您可以将其作为源文件读取)之外。不是你这样做的方式。如果您想使用您正在使用的方案来初始化这些静态对象,那么只需将声明移动到 init.hpp 标头,但保留实例化StaticLibInitializer staticLibInitializer;
在每个使用静态对象的文件中。
上述建议假设每个小部件仅使用自己的资源。如果您遇到一个小部件的资源被另一个小部件使用的情况,您将再次遇到静态初始化顺序惨败。您可以使用这样的代码来管理这种情况
StaticLibInitializer
{
void initialize()
{
static Q_INIT_RESOURCE(qtwidgets_custom_resources);
}
StaticLibInitializer()
{
initialize();
}
}
确保 StaticLibInitializer 的多重实例化仅初始化给定资源一次,然后为要在给定翻译单元中使用的每个资源实例化 StaticLibInitializer。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)