13

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 ?

4

2 に答える 2

11

静的な初期化順序の失敗に成功したため、機能しませんでした。

静的オブジェクトを初期化するコードを移動して、これらの静的オブジェクトが使用されている翻訳単位を超えるサイズにすることはできません (ソース ファイルとして読み取ることができます)。あなたがやった方法ではありません。これらの静的オブジェクトを初期化するために使用しているスキームを使用する場合は、宣言のみを init.hpp ヘッダーに移動し、StaticLibInitializer staticLibInitializer;静的オブジェクトを使用する各ファイルに設定を残します。
上記のアドバイスは、各ウィジェットが独自のリソースのみを使用することを前提としています。あるウィジェットのリソースが別のウィジェットによって使用されている状況がある場合、静的初期化順序の大失敗が再び発生します。このようなコードを使用して、この状況を管理できます

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

    StaticLibInitializer()
    {
         initialize();
    }
}

StaticLibInitializer の複数のインスタンス化が特定のリソースを 1 回だけ初期化してから、特定の翻訳単位で使用するすべてのリソースに対して StaticLibInitializer をインスタンス化するようにします。

于 2009-09-14T08:11:45.607 に答える
8

Q_INIT_RESOURCEマクロはネームスペースでは使用できません。

qtマニュアルから引用させてください:「注:このマクロは名前空間では使用できません。main()から呼び出す必要があります」。そして、これが不可能な場合でも、それを正しく行う方法の例を示しています。

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

    namespace MyNamespace
    {
     ...

     void myFunction()
     {
         initMyResource();
     }
  }

不特定の方法で使用した場合、なぜ、どの程度正確に失敗するか、失敗しないかを確認してください。関連するコードはQtCoreにあります。

于 2009-09-08T09:25:47.570 に答える