如何执行自动设置功能

How to execute an auto-setup function

在依赖另一个第三方库的库上工作时,我 运行 遇到第三方库 绝对是垃圾的问题 需要手动调用全局设置和清理功能。

int main()
{
    setup();
    //do stuff
    cleanup();
}

现在,这 完全是一坨屎 在应用程序代码中问题不大,因为它在语法上很可怕,但实际上是库中的一个难题。

应该 抽象出这些奇怪的实现细节,要求用户调用设置函数就像打自己的脸。

我试图让它们消失

//namespace scope
struct AutoMagic
{
    AutoMagic() {setup();}
    ~AutoMagic() {cleanup();}
};
AutoMagic automagic;

然后我意识到这不会跨 t运行slation 单元工作,正如在这里和那里看到的那样

因此题中的问题。

遗憾的是,你无法真正摆脱困境。您对全局实例有一个不错的想法,但实际上这对依赖关系不太适用。它还有一个可能被链接器优化掉的问题,除非你 "use" 它或者小心构建选项;我在共享库中的实体注册实例 class 遇到了这个问题。

两个可靠的选项:

  1. 将类似的 cr*p setup/teardown 函数添加到您自己的库中,这些函数遵循 setup()cleanup()
  2. 更改库

我会深表歉意,但这确实是第三方作者的错。所以你应该 k*ll th*m他们 道歉。

您可以尝试这样的操作:

std::shared_ptr<AutoMagic> init(){
    static std::shared_ptr<AutoMagic> ptr(new AutoMagic{});
    return ptr;
}

并在每个翻译单元中执行:

auto libMagic = init();

我没有测试它,但是无论哪个翻译单元先调用 init() 都应该创建对象,最后卸载的 shared_ptr 应该调用析构函数。

最后,唯一可行的就是不可移植的编译器特定代码

AutoMagic automagic __attribute__((init_priority(420));

不可移植,基本上主流的编译器都支持,除了msvc。

此属性强制变量在所有没有此属性的变量和优先级数大于此变量的变量之前初始化。

这说明 确实需要初始化优先级保证,而且显然标准还没有给出。