我有一个遗留项目,它有一个像这样的单例类:
class Singleton
{
public:
static Singleton& Instance()
{
static Singleton inst;
return inst;
}
void foo();
};
该项目使用了一个 DLL,它需要使用相同的类(部分源代码在托管应用程序和 DLL 之间共享,因此 DLL 可以访问 Singleton
)。但是,Instance
(自然地)为 DLL 返回一个不同的实例,为宿主应用程序返回一个不同的实例。这显然会导致问题。
有没有办法在 DLL 和宿主进程之间使用相同的实例? (假设二进制兼容性不是问题。)
一种方法是将 ifdef 放入您的 Instance() 方法中,以便它在您的应用程序和 dll 中表现不同。例如,让应用程序在内部调用 dll Instance() 方法的 dll 上调用导出函数。让 dll 版本像原来一样工作。
但请注意,除非您将 foo() 之类的方法设为虚拟方法,否则当应用程序调用 foo() 时,它将调用应用程序的 foo() 实现,而当 dll 调用 foo() 时,它将调用 dll 的 foo() .这充其量是困惑的,最坏的情况是有问题的。
解决这个问题的最巧妙的方法是制作一个包含公共(public)接口(interface)的纯虚拟接口(interface),然后让应用程序从 dll 中获取指向该接口(interface)类的指针并使用它。这样,应用程序就没有来自单例的代码,您将避免 future 调试的痛苦。
在共享 header 中:
struct ISingleton
{
virtual void foo()=0;
};
DLL_EXPORT ISingleton &GetSingleton();
在动态链接库中:
struct Singleton : public ISingleton
{
virtual void foo() { /* code */ }
};
ISingleton &GetSingleton()
{
static Singleton inst;
return inst;
}
在普通代码(dll 或 exe)中:
GetSingleton().foo();