2

静的ライブラリにビルドするモジュールがいくつかあります。必要に応じて、スタティック ライブラリの一部がリンクされている場合とリンクされていない場合があります。これらの静的ライブラリのいくつかには、静的 Init() メソッドを持つクラスがあります。同じくリンクされている「コア」ライブラリにも Init() メソッドがあり、以前は次のような複数の行が含まれていました。

Telephony::Init();

しかし、Telephony がこの特定のアプリケーションにリンクされない場合、コア ライブラリのコードを変更してその行を削除する必要はありません。だから私は次のようなものを試しました:

class init_hook_base
{
public:
    inline init_hook_base() { Core::AddInitHook(this); }
protected:
    friend class Core;
    virtual ~init_hook_base() {}
    virtual void operator()() const = 0;
};

template<class T>
class init_hook_t
{
protected:
    void operator()() const
    {
        T::Init();
    }
};

そして、次のような静的グローバル変数を作成します。

static init_hook_t<Telephony> telephony_init_hook;

Telephony ライブラリでは、これにより Core は Telephony::Init をコンパイル時に認識せずに間接的に呼び出すことができます。残念ながら、telephony_init_hook は構築されていません。コンストラクターに副作用があるにもかかわらず、リンク段階で取り除かれていると思います。次のようなことをします:

void Telephony::Init() { (void)telephony_init_hook; }

リンカーに関する限り、Init自体にも到達できないため、機能しません。このスタイルのモジュール性を C++ で実現する方法はありますか? GCC と VC++ の両方に同等のものがある限り、コンパイラ固有のオプションは実行可能です。ありがとう。

注: Core::AddInitHook に影響を与えるグローバルな初期化順序について懸念がある場合:

std::vector<init_hook_base*>* Core::init_hooks; //THESE ARE DELIBERATELY UNINITIALIZED!!!
unsigned char Core::init_hooks_ptr_hash[20];
bool Core::inited = false;

void Core::EnsureInitHooksContainerReady()
{
    unsigned char current_hash[20];
    sha1::calc(&init_hooks, sizeof(init_hooks), current_hash);
    if (memcmp(current_hash, init_hooks_ptr_hash, 20))
    {
        //the hash is incorrect, so init_hooks is not yet initialized;
        init_hooks = new std::vector<init_hook_base*>();
        sha1::calc(&init_hooks, sizeof(init_hooks), init_hooks_ptr_hash);
    }
}

void Core::AddInitHook(init_hook_base* init_hook)
{
    EnsureInitHooksContainerReady();
    init_hooks->push_back(init_hook);
}

void Core::Init()
{
    assert(!inited);
    PlatformInit();
    EnsureInitHooksContainerReady();
    for (auto init_hook_base : *init_hooks) {
        (*init_hook_base)();
    }
}
4

2 に答える 2

1

init_hook_t を init_hook_base から継承させる必要があります。現在、基本クラスのコンストラクターは呼び出されません。

于 2013-03-15T01:20:26.860 に答える
0

http://www.gamedev.net/topic/622861-how-to-force-global-variable-which-define-in-a-static-library-to-initialize/のようないくつかの場所で見つけた情報に基づいてC++グローバル変数は、静的ライブラリを介してリンクされた場合は初期化されませんが、ソースでコンパイルされた場合はOKです。これは、C++で信頼できる方法で実行することはできません.

于 2013-03-15T23:06:25.287 に答える