从 EXE 和 DLL 访问单一实例对象中的成员变量
Access a member variable in Singleton object from EXE and DLL
我正在为我的exe和dll编写一个具有日志记录级别的单例记录器。
记录器.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 将在同一进程/线程上运行吗?
为了跨 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宏,在语言具有布尔值之前的日子里提供类型,并且仅出于向后兼容性的原因而仍然存在。 它不应在新代码中使用。
对于本例中的单一实例对象,它将在 EXE 和 DLL 中实例化两次。
它们都是在不同的内存地址中创建的,因此,它们共享不同的成员变量。它表明它们都在彼此不认识的情况下存在。
现在,可能有两种方法可以解决此问题:
1) 通过将 Logger 类包装到 DLL
中来实例化唯一的一个记录器2) EXE 和 DLL 分别创建实例,它们需要在 EXE 和 DLL 设置日志级别
- 指向设备对象成员的指针
- 访问由unique_ptr传递的对象成员
- 引用对象成员函数的成员函数
- 将 C# 对象(包含静态对象成员)作为参数传递给 C++/CLI 程序
- Lua C API - 从C++分配和使用类的对象成员
- Rapidjson 遍历并获取复杂 JSON 对象成员的值
- 类对象成员变量在调用函数时不会更改
- 对象成员变量还是继承
- C++多态性:有没有办法找到对象成员函数的地址?
- 重载对象成员的比较运算符
- 获取未初始化对象成员的地址是否定义良好?
- 在优先级队列被推送到队列后,如何编辑对象成员
- 为什么在这里调用析构函数,以及在调用该对象析构函数后如何调用对象成员函数?
- 通过 std::bind 从对象成员检索值
- 保留对象成员变量的本地副本
- 有没有办法为静态对象成员定义一个符合开关标准的常量?
- 没有默认构造函数的对象成员的 wig setter
- 对象成员数组C++默认初始化
- 如何在数组中添加对象成员
- 使用聚合创建和关联两个不同的对象成员