Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
初始化嵌入在静态库中的qt资源 我有下一个情况:我需要在独立的静态库中创建小部件,然后它将与最终的应用程序连接(Visual C++ 9,Qt 4.5)。 这个静态小部件库包含一些资源(图标),由几个.cpp文件组成(每个文件都包含独立的小部件)。据我所知,若我在静态库中使用它们(资源),我必须初始化qt资源系统,并调用“Q_INIT_resource(resource_file_name)”。我用下一个代码(在静态库中的每个.cpp文件中)解决了这个问题: #包括 名称空间{ 结构静态初始化器 { StaticLibInitializer() { Q_INIT_资源(qtwidts_自定义_资源); } }; StaticLibInitializer StaticLibInitializer; } // ... 小部件代码。。。。_C++_Qt_Static Libraries_Static Order Fiasco - Fatal编程技术网

初始化嵌入在静态库中的qt资源 我有下一个情况:我需要在独立的静态库中创建小部件,然后它将与最终的应用程序连接(Visual C++ 9,Qt 4.5)。 这个静态小部件库包含一些资源(图标),由几个.cpp文件组成(每个文件都包含独立的小部件)。据我所知,若我在静态库中使用它们(资源),我必须初始化qt资源系统,并调用“Q_INIT_resource(resource_file_name)”。我用下一个代码(在静态库中的每个.cpp文件中)解决了这个问题: #包括 名称空间{ 结构静态初始化器 { StaticLibInitializer() { Q_INIT_资源(qtwidts_自定义_资源); } }; StaticLibInitializer StaticLibInitializer; } // ... 小部件代码。。。。

初始化嵌入在静态库中的qt资源 我有下一个情况:我需要在独立的静态库中创建小部件,然后它将与最终的应用程序连接(Visual C++ 9,Qt 4.5)。 这个静态小部件库包含一些资源(图标),由几个.cpp文件组成(每个文件都包含独立的小部件)。据我所知,若我在静态库中使用它们(资源),我必须初始化qt资源系统,并调用“Q_INIT_resource(resource_file_name)”。我用下一个代码(在静态库中的每个.cpp文件中)解决了这个问题: #包括 名称空间{ 结构静态初始化器 { StaticLibInitializer() { Q_INIT_资源(qtwidts_自定义_资源); } }; StaticLibInitializer StaticLibInitializer; } // ... 小部件代码。。。。,c++,qt,static-libraries,static-order-fiasco,C++,Qt,Static Libraries,Static Order Fiasco,与第一种方法不同,我在静态库项目中创建了单独的init.cpp文件,其中包含初始化代码(以避免在每个.cpp文件中都包含初始化代码),但这不起作用 为什么这不起作用 使用StaticLibInitializer的这种方法在各种编译器和平台之间安全且可移植吗?Q\u INIT\u资源宏不能在命名空间中使用 让我引用qt手册中的一句话:“注意:这个宏不能在名称空间中使用。它应该从main()调用。”。即使它给了你一个例子,如果这是不可能的,如何做正确的: inline void initMyRe

与第一种方法不同,我在静态库项目中创建了单独的init.cpp文件,其中包含初始化代码(以避免在每个.cpp文件中都包含初始化代码),但这不起作用

为什么这不起作用


使用StaticLibInitializer的这种方法在各种编译器和平台之间安全且可移植吗?

Q\u INIT\u资源宏不能在命名空间中使用

让我引用qt手册中的一句话:“注意:这个宏不能在名称空间中使用。它应该从main()调用。”。即使它给了你一个例子,如果这是不可能的,如何做正确的:

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

    namespace MyNamespace
    {
     ...

     void myFunction()
     {
         initMyResource();
     }
  }

如果您以未指定的方式使用它,请查看您自己为什么以及如何确切地失败或不失败。相关代码在QtCore中。

它不起作用,因为您设法被攻击

您不能将初始化静态对象的代码移动到使用这些静态对象的转换单元(您可以将其作为源文件读取)之外。不是你那样做的。如果要使用用于初始化这些静态对象的方案,请仅将声明移动到init.hpp头,但保留instations
StaticLibInitializer StaticLibInitializer
以上建议假设每个小部件只使用自己的资源。若您遇到一个小部件的资源被另一个小部件使用的情况,那个么您将再次陷入静态初始化顺序的失败。您可以使用这样的代码来管理这种情况

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

    StaticLibInitializer()
    {
         initialize();
    }
}

为了确保StaticLibInitializer的多个实例化只会初始化给定的资源一次,然后为给定翻译单元中要使用的每个资源实例化StaticLibInitializer。

但在第一种方法中(当我在静态库的每个.cpp文件中包含代码时),这是有效的(即使使用匿名命名空间)使用上面的
inline
并不能为您带来任何好处,因为您不能保证编译器会遵守它。不尊重这个关键词是符合C++标准的。因此,如果此解决方案基于内联函数将被内联的假设,那么它就被破坏了。
inline
函数的语义稍有不同,尤其是在涉及ODR时。考虑到我们不知道
Q_INIT_RESOURCE
在所有平台上的宏扩展,很难判断是否需要它。把它放在那里当然是合理的。在我目前的情况下,我有三个.cpp文件(每个文件实现自己的小部件,其中两个使用.qrc文件中的资源),但是初始化代码,我在最初的问题中给出的,只在其中一个文件中,所有文件都可以正常工作(100%,而不是50/50)。所以我不明白,为什么当我把初始化代码放在单独的init.cpp文件中时,我不能使用我的资源,但是当这个小部件的.cpp文件中的这个代码都可以正常工作时……这没关系,它现在可以正常工作:)它只是偶然工作的。当您开始使用另一个编译器或同一编译器的另一个版本时,它可能会停止工作。这是未定义的行为。它现在起作用的原因是,当您在小部件的一个文件中有初始化代码时,编译器会首先初始化您的资源。纯属运气,仅此而已。如果您不想让您的程序在晴朗的一天0%运行,请按照说明操作,以避免静态初始化顺序失败。静态初始化顺序是由编译器在编译阶段定义的,还是在程序重新启动(无需重新编译)时顺序可能不同?否,它在程序启动时不会变化,它通常取决于链接顺序。有些编译器允许使用扩展名指定转换单元的初始化顺序。非常感谢您的解释!
StaticLibInitializer
{
    void initialize()
    {
        static Q_INIT_RESOURCE(qtwidgets_custom_resources);
    }

    StaticLibInitializer()
    {
         initialize();
    }
}