在main()之前,在静态库中运行代码,此时链接器看不到对它的其他引用

时间:2013-03-14 01:50:27

标签: c++ static-libraries compiler-optimization

我有几个构建到静态库的模块。根据需要,可能会链接某些静态库,而其他静态库可能不会链接。其中一些静态库具有静态Init()方法的类。 “Core”库也链接在一起,也有一个Init()方法,之前它包含多行,如:

Telephony::Init();

但是如果Telephony不会被链接到这个特定的应用程序,我不想修改Core库的代码来删除该行。所以我尝试了类似的东西:

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)();
    }
}

2 个答案:

答案 0 :(得分:1)

您需要从init_hook_base继承init_hook_t。 就像现在一样,基类构造函数不会被调用。

答案 1 :(得分:0)