我有一个遗留项目,它有一个像这样的单例类:
class Singleton
{
public:
static Singleton& Instance()
{
static Singleton inst;
return inst;
}
void foo();
};
项目使用需要使用相同类的DLL(源的一部分在托管应用程序和DLL之间共享,因此DLL可以访问Singleton
)。但是,Instance
(自然地)返回DLL的不同实例,而托管应用程序则返回不同的实例。这显然会导致问题。
有没有办法在DLL和托管进程之间使用相同的实例? (我们假设二进制兼容性不是问题。)
答案 0 :(得分:2)
通过移动静态Singleton inst,我解决了同样的问题(例如,在库中,在其他库中以及在主应用程序中使用的类);进入cpp文件。
Foo.h
class Foo{
public:
static Foo *getInstance();
...
Foo.cpp
Foo *Foo::getInstance(){
static Foo instance;
return &foo;
}
静态变量然后在库中的一个位置(so / dll),一切运行正常。我甚至可以使用不同的头文件进行导出。
答案 1 :(得分:1)
一种方法是在您的Instance()方法中放置一个ifdef,以便它在您的app和dll中表现不同。例如,让应用程序在内部调用dll Instance()方法的dll上调用导出的函数。让dll版本像原来一样工作。
请注意,除非你制作像foo()虚拟的方法,当app调用foo()时,它会调用app的foo()实现,当dll调用foo()时,它会调用dll的foo() 。这最好是混乱而且最坏的问题。
最好的方法是创建一个包含公共接口的纯虚拟接口,然后让app从dll获取指向此接口类的指针并使用它。这样,该应用程序没有来自Singleton的代码,您将节省未来的调试痛苦。
在共享标题中:
struct ISingleton
{
virtual void foo()=0;
};
DLL_EXPORT ISingleton &GetSingleton();
在Dll:
struct Singleton : public ISingleton
{
virtual void foo() { /* code */ }
};
ISingleton &GetSingleton()
{
static Singleton inst;
return inst;
}
在通用代码(dll或exe)中:
GetSingleton().foo();
答案 2 :(得分:0)
常见的解决方案是让另一个dll保存单例但不使用静态成员实现。例如,见answer。