从 EXE 和 DLL 访问单一实例对象中的成员变量

Access a member variable in Singleton object from EXE and DLL

本文关键字:对象 成员 变量 实例 单一 EXE DLL 访问      更新时间:2023-10-16

我正在为我的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 设置日志级别