从EXE和DLL访问Singleton对象中的成员变量

时间:2012-04-19 08:11:29

标签: java c++ logging mfc singleton

我正在编写一个单例记录器,其中包含我的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将在同一进程/线程上运行吗?

2 个答案:

答案 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

设置日志级别