したがって、単純な関数が作成されました。
void dbg(const char * AMsg);
これはログに行を書きました。 そのような機能は十分ではなく、次の形式で書き直されたことがすぐに判明しました。
void dbg(const char * AFmt, ...);
つまり 現在、彼女はvfprintf()関数を使用して、フォーマットされた文字列をファイルに書き込みました。 呼び出しの数が増えるにつれて、ファイルにさらに2つのパラメーター、つまり__LINE__と__FILE__を書き込みたいと思いました。 各関数呼び出しでこれらの2つのパラメーターを転送したくなかったため、dbg()関数のマクロラッパーを作成し、可変数のパラメーターを取得し、元の関数を呼び出し、最初の2つのパラメーターでファイル名と行番号を渡すことにしました。
グーグル、私はかなりいい解決策を見つけました-クラスを記述し、その中の演算子()をオーバーロードします。 テストプロジェクトをスケッチし、新しいマクロと修正された関数をテストし、結果に満足しました。 その後、ファイルを元のプロジェクトに接続し、「StdAfx.h」のhファイルをヒントして、「ビルド」をクリックしました。 そして、私は深い失望に追われました。 プロジェクトの一部が純粋なCで記述されていることが判明しました。これは私のクラスが念頭に置いていました。
まだグーグルで、私はそのような解決策を見つけました 。 しかし、悲しいかな、私はVC6を使用しました...
そして、アイデアが思いつきました-まあ、マクロが__FILE__および__LINE__パラメーターを受け取る関数に置き換えられた場合、それらをどこかに保存して、元のdbg()関数へのポインターを返すということです。 そして、この関数は保存されたパラメーターを読み取り、ファイルに書き込みます。 グローバル変数にパラメーターを保存することにしました。 また、変数自体は、マルチスレッド作業中にレーキにぶつからないように、__ declspec(スレッド)として宣言します。 Bは最後に何が起こったかです:
hファイル
// File debug_info.h #ifndef __DEBUG_INFO_H #define __DEBUG_INFO_H // , typedef void (* DbgFuncType)(const char * AFmt, ...); // , __FILE__ __LINE__, #ifdef __cplusplus extern "C" #endif DbgFuncType DbgFuncRet(const char* AFile, int ALine); // #define dbg DbgFuncRet(__FILE__, __LINE__) #endif
cppファイル
// File debug_info.h #include "StdAfx.h" #include <stdio.h> #include <stdarg.h> __declspec(thread) char __File__[MAX_PATH]; __declspec(thread) int __Line__; void DbgFunc(const char * AFmt, ...) { FILE * log; if (fopen_s(&log, log_name, "a")) return; va_list args; va_start(args, AFmt); vfprintf(log, AFmt, args); fprintf(log, "File: \"%s\", Line: %d\n", __File__, __Line__); fclose(log); va_end(args); } DbgFuncType DbgFuncRet(const char* AFile, int ALine) { strcpy_s(__File__, MAX_PATH, AFile); __Line__ = ALine; return &DbgFunc; }
以上です。 私が詳しく述べたいのは、関数DbgFuncRet()の宣言だけです。
#ifdef __cplusplus extern "C" #endif DbgFuncType DbgFuncRet(const char* AFile, int ALine);
なぜなら ヘッダーはcファイルとcppファイルの両方で接続されているため、名前変換プログラムは関数に異なる装飾を使用します。 そして、そのような発表は、コンパイラに常にC装飾を使用するように伝えます。