2

私は自分の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プロジェクトがログファイルに書き込めるように、DLLプロジェクトにSetLogLevel()を要求する必要があるということです。

上記のLogger.hで問題を見つけられる人はいますか?EXEとDLLは同じプロセス/スレッドで実行されるため、シングルトンはメンバー変数を含むオブジェクトの1つのインスタンスを共有しませんか?

4

2 に答える 2

1

VC ++のDLL境界を越えてエンティティ(関数、オブジェクトなど)を共有するには、エンティティ__declspec(dllexport)をエクスポートする__declspec(dllimport)DLLとインポートするDLLで宣言する必要があります。これは通常、条件付きで定義されたマクロを使用して行われます。エクスポータをコンパイルしてリンクするときLOGGER_DLLに、コンパイラオプションの行に沿ってプリプロセッサ定義を追加し、DLLの共通ヘッダーファイルに次のように追加します。

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

次に、クラス定義で:

class LOGGER_EXPORTS Logger
{
    // ...
};

(そして他の2つの簡単なコメント:名前の接頭辞としての単一の大文字CはMicrosoftの規則であり、クラスがMicrosoftライブラリで定義されており、ユーザーコードで使用されるべきではないことを示します。このような接頭辞の目的の1つは名前の衝突を避けてください。 また、C ++のブール型はスペルboolであり、言語がブール型になる前の時代に提供されたMicrosoftマクロであり、下位互換性の理由でのみ存在するはずです。新しいコードで使用することはできません。)BOOLBOOL

于 2012-04-19T09:01:40.557 に答える
0

この場合のシングルトンオブジェクトの場合、EXEとDLLで2回インスタンス化されます。

どちらも異なるメモリアドレスで作成されているため、異なるメンバー変数を共有しています。それは、それらの両方がお互いを知らずに存在することを示しています。

現在、この問題を解決するにはおそらく2つの方法があります
。1)LoggerクラスをDLLにラップして1つのロガーのみをインスタンス化します
。2)EXEとDLLはインスタンスを個別に作成し、EXEとDLLでログレベルを設定する必要があります。

于 2012-04-20T02:55:59.240 に答える