混合共享/静态库时静态成员的多个副本

Multiple copies of static members when mixing shared/static libs

本文关键字:副本 静态成员 共享 静态 混合      更新时间:2023-10-16

情况:

我有:

class Platform {
public:
   Platform() { count++; cout << getCount();}
   static int getCount() { return count; }
private:
   static int count;
}

创建为静态库。

考虑创建动态库扩展

class __declspec(dllimport/dllexport) DerivedPlatform : public Platform {
}

是的,我知道我是从非 dll 接口类派生的。

Per:静态字段是继承的吗?,永远应该只有一个计数实例。

这是棘手的部分,我实际上最终得到了两个不同的计数副本(即使计数被声明为静态)。即,在 dll 中加载并调用 registerPlatforms() 时,它会递增一个不同的计数对象:

int main() {
   Platform::count = 0;
   Platform A; // increases count by 1, cout shows 1
   loadPlugin(); // loads the shared library DerivedPlatform
   DerivedPlatform D; // increases count by 1 again, cout shows 2
   cout << Platform::getCount(); // shows 1 !!!!!!
}

我不知道如何解决这个问题,即如何确保只有一个静态变量持续存在。显然,DLL 有自己的静态变量堆 - 所以为什么会发生这种情况是有道理的。

是的,当您将静态库链接到可执行文件和 DLL 时,就会发生这种情况。在链接时,两人都不了解对方,所以他们都得到了一份副本。对于通常不会造成任何伤害的代码本身,但对于静态变量来说,这可能是一个真正的麻烦。

您需要重新构建解决方案,以便静态库位于 DLL 中,可以是现有库,也可以是全新的第三个库。或者消除所有静态变量。