dll 中的 C++ 模板单例 [英] C++ Template Singletons in a dll

查看:45
本文介绍了dll 中的 C++ 模板单例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 dll A 中,我有一个模板单例:

In dll A I have a template singleton:

template <class T>
class Singleton
{
public:
  static T &instance()
  {
    static T _instance;
    return _instance;
  }

private:
  //All constructors are here
};

在 Dll B 中,我定义了一个 Logger 类.Dlls C、D 和 E 使用记录器,它的访问方式如下:

In Dll B I define a class Logger. Dlls C,D and E use the Logger and it is accessed like this:

Singleton<Logger>::instance();

问题是每个dll都实例化了自己的

The problem is that each dll instantiates its own copy of

Singleton<Logger>.

而不是使用相同的单例实例.我知道这个问题的解决方案是使用 extern 模板.即 dll C、D 和 E 必须包含

instead of using the same singleton instance. I understand that the solution to this problem is using extern templates. That is dlls C,D and E have to include

extern template class Singleton<Logger>;

和dll B必须包括:

and dll B must include:

template class Singleton<Logger>;

这仍然会导致创建多个模板实例.我尝试将 extern 放入所有 dll 中,但仍然无效 我尝试从所有 dll 中删除 extern,但仍然无效.这不是实现模板单例的标准方法吗?这样做的正确方法是什么?

This still cause more than one template instance to be created. I tried putting the extern in all the dlls and it still didn't work I tried removing the extern from all the dlls and it still didn't work. Is this not the standard way to implement template singletons? What is the correct way to do this?

推荐答案

对我有用的技巧是将 __declspec(dllexport) 添加到单例的模板定义中;将模板实现从类定义中分离出来,并且只包含在 A DLL 中的实现;最后,通过创建一个调用 Singleton::instance() 的虚拟函数,强制在 A DLL 中实例化模板.

The trick that works for me is to add __declspec(dllexport) to the singleton's template definition; split the template implementation from the class definition and only include the implementation in the A DLL; and finally, force the template to be instantiated in the A DLL by creating a dummy function that calls Singleton<Logger>::instance().

所以在你的 A DLL 的头文件中,你像这样定义 Singleton 模板:

So in your A DLL's header file, you define the Singleton template like this:

template <class T>
class __declspec(dllexport) Singleton {
public:
  static T &instance();
};

然后在您的 A DLL 的 cpp 文件中定义模板实现,并像这样强制 Singleton 实例化:

Then in your A DLL's cpp file you define the template implementation, and force an instantiation of Singleton<Logger> like this:

template <class T>
T &Singleton<T>::instance() {
  static T _instance;
  return _instance;
};

void instantiate_logger() {
  Singleton<Logger>::instance();
}

至少使用我的编译器,我不需要从任何地方调用 instantiate_logger.只要它存在就会强制生成代码.因此,如果此时转储 A DLL 的导出表,您应该会看到 Singleton::instance() 的条目.

With my compiler at least, I don't need to call instantiate_logger from anywhere. Just having it exist forces the code to be generated. So if you dump the A DLL's export table at this point, you should see an entry for Singleton<Logger>::instance().

现在在您的 C DLL 和 D DLL 中,您可以包含带有 Singleton 模板定义的头文件,但是由于没有模板实现,编译器将无法创建任何该模板的代码.这意味着链接器最终会抱怨 Singleton<Logger>::instance() 的未解析外部变量,但您只需要在 A DLL 的导出库中进行链接即可解决该问题.

Now in your C DLL and D DLL, you can include the header file with the template definition for Singleton, but because there is no template implementation, the compiler won't be able to create any code for that template. This means the linker will end up complaining about unresolved externals for Singleton<Logger>::instance(), but you just have to link in the A DLL's export library to fix that.

最重要的是,Singleton::instance() 的代码仅在 DLL A 中实现,因此您永远不能拥有多个实例.

The bottom line is that the code for Singleton<Logger>::instance() is only ever implemented in DLL A, so you can never have more than one instance.

这篇关于dll 中的 C++ 模板单例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆