使用跨DLL边界的单例
我有一个遗留项目,有一个单例类如下:
I have a legacy project which has a singleton class like this:
class Singleton
{
public:
static Singleton& Instance()
{
static Singleton inst;
return inst;
}
void foo();
};
项目使用一个需要使用相同类的DLL(部分源是托管应用程序和DLL,因此DLL可以访问 Singleton
)。但是, Instance
(当然)会为DLL返回一个不同的实例,为主机应用程序返回一个不同的实例。这显然会导致问题。
The project uses a DLL which needs to use the same class (part of the source is shared between the hosting application and the DLL, so the DLL has access to Singleton
). However, Instance
(naturally) returns a different instance for DLL, and a different one for the hosting application. This obviously causes problems.
有没有办法在DLL和主机进程之间使用相同的实例? (假设二进制兼容性不是问题。)
Is there a way to use the same instance between the DLL and the hosting process? (let's assume that binary compatibility is not an issue.)
一种方法是在你的Instance方法,使其在您的应用程序和DLL中的行为不同。例如,让应用程序调用dll上的一个导出函数,它在内部调用dlls Instance()方法。
One way would be to put an ifdef in your Instance() method so that it behaved differently in your app and dll. For example, have the app one call an exported function on the dll which internally calls the dlls Instance() method. Have the dll version work as originally.
请注意,除非你使用像foo()virtual这样的方法,当应用程序调用foo()时,它会调用应用程序的实现foo(),当dll调用foo()时,它将调用dll的foo()。这是最好的混乱和最坏的问题。
Beware though, unless you make methods like foo() virtual, when the app calls foo() it will call the app's implementation of foo(), and when the dll calls foo() it will call the dll's foo(). This is messy at best and problematic at worst.
最简单的方法是使一个纯虚拟接口包含公共接口,然后让应用程序获得一个指针到这个接口类从dll和使用。
The neatest way around this is to make a pure virtual interface which contains the public interface, then have the app get a pointer to this interface class from the dll and use that. This way the app has no code from Singleton and you will save yourself future debug pain.
在共享标题中:
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)中:
In common code (dll or exe):
GetSingleton().foo();