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++ 全局变量在通过静态库链接时未初始化,但在使用源代码编译时可以,这在 C++ 中以任何可靠的方式都不可行。

于 2013-03-15T23:06:25.287 回答