我有一个Logging类,它可以简化为:
template <int TARGET>
struct Logging
{
static ostream * sOstream;
static void log(const char * _txt);
static void set_log_file(const char * _file_name)
{
sOstream = new ofstream(_file_name);
}
}
整个过程在一个二进制文件中运行良好。但是,在使用DLL的可执行文件中调用了Logging<TARGET_DEBUG>::set_log_file(someFilePath.c_str());
之后,我希望能够在DLL中使用Logging<TARGET_DEBUG>::log("some message");
。最初,它不起作用,因为我没有使用__declspec(dllexport)
导出类。然而,当我将适当的宏添加到日志类定义中(仅标题)时,我会收到一系列错误消息:
警告C4273:"sStream":dll链接不一致//为什么指针会出现这种情况?
错误C2491:"日志记录::sStream":不允许定义dllimport静态数据成员
应用程序中的其他各种类都可以顺利导出/导入,但这是我试图在二进制文件之间共享的唯一模板类。这不是一个我过于熟悉的领域,所以:我如何才能让这项工作如我所愿?请注意,EXE包括带有__declspec(dllimport)
的Logging结构,带有__declspec(dllexport)
的DLL
您需要将显式模板实例化与__declspec
修饰符结合使用。这将导致模板成员生成并从DLL导出。它还将告诉访问模板成员的应用程序,应该导入而不是生成模板成员。
下面的代码进入DLL项目中的头文件
// Normal __declspec import/export stuff
// Define EXPORT_LOGGING in the preprocessor settings of your DLL project
#ifdef EXPORT_LOGGING
#define LOG_EXPORT __declspec(dllexport)
#else
#define LOG_EXPORT __declspec(dllimport)
#endif
template <int TARGET>
struct LOG_EXPORT Logging
{
static std::ostream * sOstream;
static void log(const char * _txt)
{
// ... logging code ...
}
static void set_log_file(const char * _file_name)
{
sOstream = new std::ofstream(_file_name);
}
};
下面的代码进入DLL项目中的.cpp
文件
// static member for TARGET_DEBUG
std::ostream* Logging<TARGET_DEBUG>::sOstream = nullptr;
// explicit template instantiation
template struct Logging<TARGET_DEBUG>;