模板、静态和 dll
Template, statics and dll
>我正在尝试导出定义中带有静态变量的函数模板。
.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/主.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)
}
您需要单独标记每个模板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();
}
相关文章:
- 从 exe 和 dll 访问静态库中的 extern 变量
- 模板、静态和 dll
- 如何使用 CMake 生成链接到静态库的 DLL
- 静态链接 Visual Studio dll 到动态链接的 sfml 项目
- C++ dll 定义静态成员
- 我可以加载与库静态链接的 dll 吗?
- DLL 链接静态库 - 未使用函数中未解析的链接器符号
- C ++:DECLSPEC,静态库和DLL
- 在DLL中,C 静态矢量会失去元素
- DLL – 在 DLL 初始化时填充的静态向量,向客户端程序返回零大小
- 使用不同.dll(导出相同的符号)静态链接的二进制文件
- dll导出函数的函数符号来自静态链接库
- 如何初始化堆,以便静态构造函数可以在常规 MFC dll 中使用堆?
- 如何在VS项目中静态链接没有dll文件的cpprest?
- 将静态库转换为 DLL 会导致在 main 之前出现访问冲突
- dll 中静态成员变量的生存期
- 哪种方法更好获取静态链接DLL的模块句柄(HMODULE) - 使用GetModuleHandleEx()或LoadLibrary()?
- 静态地将Google Protobuf lib链接到DLL库中
- 在dll中静态对象的破坏之前,要终止工作线程(但不是.exe)
- c++DLL\静态库名称问题