2012-04-19 54 views
2

我正在为我的exe和dll编写一个具有日志记录级别的单例记录器。从EXE和DLL访问Singleton对象的成员变量

的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都能够将任何内容写入同一个日志文件。

现在的结果是,我将需要向SetLogLevel()请求DLL项目,以便DLL项目能够写入日志文件。

任何人都可以在上面的Logger.h上发现问题吗? Singleton不会共享包含成员变量的一个对象实例,因为EXE & DLL将在同一个进程/线程上运行?

回答

0

对于这种情况下的单例对象,它将在EXE和DLL中实例化两次。

它们都是在不同的内存地址中创建的,因此它们共享不同的成员变量。它表明两者都存在而不知道对方。

现在,大概有两个到解决这个问题的办法:
1)通过包装Logger类为DLL实例只有一个记录器
2)EXE和DLL分别创建实例,就需要设置日志级别在EXE和DLL上

1

为了在VC++共享实体(函数,对象等)翻过DLL 边界,你需要声明他们__declspec(dllexport)在 其中出口他们DLL,并__declspec(dllimport)在导入这些DLL 。这通常通过在某处有条件地 定义的宏完成:在编译和链接导出器时, 将沿着LOGGER_DLL到 编译器选项的行添加预处理器定义,并且在DLL的公用头文件中, 喜欢:

#ifdef LOGGER_DLL 
#define LOGGER_EXPORTS __declspec(dllexport) 
#else 
#define LOGGER_EXPORTS __declspec(dllimport) 
#endif 
类定义

然后:

class LOGGER_EXPORTS Logger 
{ 
    // ... 
}; 

(以及其他两个快捷评论:一个大写C作为前缀名称 是MICR osoft约定,表示该类在Microsoft库中定义了一个 ,不应在用户代码中使用;其中一个 这样的前缀的目的是为了避免名称冲突。而C++中的布尔型 类型拼写为bool,而不是BOOL。我认为,BOOL是一个 Microsoft宏,在语言具有布尔型 类型之前的几天提供,并且仅出于向后兼容性的原因而存在。它不应该用于新代码中。)