在DLL边界使用单例

时间:2014-01-24 13:26:44

标签: c++ dll singleton

我有一个遗留项目,它有一个像这样的单例类:

class Singleton
{
public:
    static Singleton& Instance() 
    {
        static Singleton inst;
        return inst;
    }

    void foo();
};

项目使用需要使用相同类的DLL(源的一部分在托管应用程序和DLL之间共享,因此DLL可以访问Singleton)。但是,Instance(自然地)返回DLL的不同实例,而托管应用程序则返回不同的实例。这显然会导致问题。

有没有办法在DLL和托管进程之间使用相同的实例? (我们假设二进制兼容性不是问题。)

3 个答案:

答案 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