我正在编写一个单例记录器,其中包含我的exe和dll的日志记录级别。
Logger.h:
#define LOG CLogger::GetInstance().Log
#define LOG_PATH _T(".\\LogFile\\Logger.log")
enum eLogLevel { NONE=0, ERR, WARNING, USER, SYSTEM, DEVELOPER };
class CLogger
{
public:
//Construcor & Destructor
CLogger();
virtual ~CLogger();
//Singleton
static CLogger& GetInstance();
//For logging level preference
//Example: WARNING -> Log only ERR & WARNING messages
//Default = NONE
virtual void SetLogLevel(eLogLevel eLevel);
//Logging
virtual void Log(eLogLevel eLevelType, CString szText);
protected:
//Open & Close the log after used
virtual void CloseLog();
virtual BOOL OpenLog();
CStdioFile m_File;
CString m_szFile;
eLogLevel m_eLevel;
BOOL m_bFileOpened;
};
这个想法是,EXE项目需要包含Logger.cpp& Logger.h,负责设置日志记录级别。
同时,DLL项目需要包含Logger.cpp& Logger.h,但不需要设置日志记录级别,因为它将遵循EXE项目的日志记录级别。
EXE& DLL应该能够将任何内容写入同一个日志文件。
现在的结果是,我需要向DLL项目询问SetLogLevel(),以便DLL项目能够写入日志文件。
有人可以在上面的Logger.h上发现问题吗? Singleton不会共享一个对象实例,包括成员变量,如EXE& DLL将在同一进程/线程上运行吗?
答案 0 :(得分:1)
为了共享DLL中的实体(函数,对象等)
VC ++中的边界,你需要声明它们__declspec(dllexport)
导出它们的DLL,以及DLL中的__declspec(dllimport)
导入它们。这通常通过有条件的方式完成
在某处定义宏:在编译和链接导出器时,你
将添加一个预处理器定义沿着LOGGER_DLL
的行
编译器选项,以及DLL的公共头文件
像:
#ifdef LOGGER_DLL
#define LOGGER_EXPORTS __declspec(dllexport)
#else
#define LOGGER_EXPORTS __declspec(dllimport)
#endif
然后在课程定义中:
class LOGGER_EXPORTS Logger
{
// ...
};
(以及另外两个快速评论:单个大写C
作为名称的前缀
是一个Microsoft约定,表明该类是在一个。中定义的
Microsoft库,不应该在用户代码中使用;其中一个
这种前缀的目的是避免名称冲突。和布尔值
C ++中的类型拼写为bool
,而不是BOOL
。我认为BOOL
是一个
Microsoft宏,在语言有布尔值之前的几天提供
类型,并且仅出于向后兼容性的原因仍然存在。它
不应该在新代码中使用。)
答案 1 :(得分:0)
对于单例对象,在这种情况下,它将在EXE和DLL中实例化两次。
它们都是在不同的内存地址中创建的,因此,它们共享不同的成员变量。它表明它们之间存在而不相互了解。
现在,有两种方法可以解决这个问题:
1)通过将Logger类包装到DLL中来实例化唯一的一个记录器
2)EXE和DLL分别创建实例,需要在EXE和DLL