【问题标题】:Template, statics and dll模板、静态和 dll
【发布时间】:2018-09-09 09:06:46
【问题描述】:

我正在尝试导出定义中包含静态变量的函数模板。

.dll/Foo.h:

#ifdef _DLL
#define API __declspec(dllexport)   
#else  
#define API __declspec(dllimport)   
#endif  

class API Foo
{
  public:
  template<typename T>
  static T& Get()
  {
    static T _instance;
    return _instance;
  }

  static void Set();
}

我希望 .dll 和 .exe 的调用引用同一个“_instance”对象。我知道我可以通过在 .cpp 中定义静态变量来做到这一点。但在这种情况下,我正在处理模板,所以我有点卡住了。

编辑: 正在发生的事情的示例..

.dll/Foo.cpp:

void Foo::Set()
{
   Foo::Get<int>() = 10;
}

.exe/main.cpp:

int main()
{
  auto & x = Foo::Get<int>();
  x = 3;
  std::cout << x; // 3
  Foo::Set();
  std::cout << x; // 3 (I want it to be 10)
}

【问题讨论】:

  • @AlanBirtles 我对导出上述函数没有任何问题。我的问题是我想在我的 .dll 和 .exe 项目之间共享函数中定义的静态变量(在本例中为“静态 T _instance”)。

标签: c++ templates static visual-studio-2017 c++17


【解决方案1】:

您需要用API__declspec(dllexport)__declspec(dllimport)单独标记每个模板,而不是将其内联到类代码中。

Foo.h 文件是:

#ifdef _DLL
#define API __declspec(dllexport)   
#else  
#define API __declspec(dllimport)   
#endif  

class API Foo
{
public:
    template<typename T> 
    API static T& Get();

    static void Set();
};

请注意,我们将Get()API 分开标记,尽管所有Foo 类也用API 标记(实际上类标记对模板功能没有影响,因此需要将其标记分开)。并且这里没有实现Get - 导出的函数无论如何都不能内联。

所以 dll 代码 (Foo.cpp) 必须如下所示:

#include "foo.h"

template<typename T>    
API T& Foo::Get()
{
    __pragma(message("__imp_" __FUNCDNAME__)) // for debug
    static T _instance;
    return _instance;
}

void Foo::Set()
{
    Foo::Get<int>() = 10;
}

请注意,我们在函数体的实现中再次显式使用API (__declspec(dllexport))。这一点很重要——如果你在这里跳过API,编译器不会警告你,但是没有这个——Get 将不会被导出。

确定此时所有正确 - 复制由__pragma(message("__imp_" __FUNCDNAME__)) 生成的字符串(看起来像__imp_??$Get@H@Foo@@SAAEAHXZ 并搜索完全正确(符号到符号) 此字符串在创建的 .lib 文件中 - 在您构建 dll 之后。如果存在 - 一切正常,否则没有意义继续(使用 exe)

在 exe 中:

#include "../foo_dll/foo.h"

Foo::Get<int>() = 3;
Foo::Set();
if (Foo::Get<int>() != 10)
{
    __debugbreak();
}

【讨论】:

    猜你喜欢
    • 2019-06-21
    • 1970-01-01
    • 2020-02-19
    • 1970-01-01
    • 2013-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-11
    相关资源
    最近更新 更多