この記事は2019年02月22日に投稿しました。
目次
- 作者: 堀義博
- 出版社/メーカー: 技術評論社
- 発売日: 2017/11/17
- メディア: Kindle版
- この商品を含むブログを見る
1. はじめに
こんにちは、iOSのエディタアプリPWEditorの開発者の二俣です。
今回は業務で使用しているMFCでログにファイル名、関数名、行番号、メッセージを表示する方法についてです。
2. MFCでログにファイル名、関数名、行番号、メッセージを表示する
MFCでログにファイル名、関数名、行番号、メッセージを表示する方法ですが、以下のような処理になります。
ポイントはLOGマクロです。
LOGマクロで呼び出しているのが以下の定義済みマクロです。
これらは呼び出し時点の、ファイルパス名、関数名、行番号、可変長引数に展開されます。
そのためこれらのマクロをログ出力する関数本体(例では"Log"関数)で呼び出すと、常にLog関数の情報で展開されます。
そのためLOGマクロで展開する必要があります。
マクロ名 | 内容 |
---|---|
__FILE__ | ファイルパス名 ファイル名ではないので注意 |
__FUNCTION__ | 関数名 |
__LINE__ | 行番号 |
__VA_ARGS__ | 可変長引数 |
Log関数の現在時刻を取得する方法は
で紹介した方法です。
またファイルパス名からファイル名を取得する方法は
で紹介した方法です。
可変長引数を1つの文字列に整形する方法は
で紹介した方法です。
Log.h
// ログ文字列を出力する関数のプロトタイプ宣言 // (使う側は直接この関数を呼び出さないこと) CString Log(CString file, CString function, int line, CString fmt, ...); // 使う側が呼び出すマクロ #define LOG(fmt, ...) Log(_T(__FILE__), _T(__FUNCTION__), __LINE__, fmt, ##__VA_ARGS__) // 可変長引数を1つの文字列に整形する際使用するバッファサイズ #define BUFFER_SIZE (1024)
Log.cpp
/** * @brief コンソールにログ文字列を出力します。 * "LOG"マクロから呼び出されます。 * 出力フォーマット:YYYY/MM/DD HH:MM:SS ファイル名 関数名(行番号) メッセージ * * @param [in] file ファイルパス名 * @param [in] function 関数名 * @param [in] line 行番号 * @param [in] fmt フォーマット文字列 * @param [in] ... 可変長引数 * @return フォーマットされたログ文字列 */ CString Log(CString file, CString fuction, int line, CString fmt, ...) { // ログ出力する時点の年月日時分秒(YYYY/MM/DD HH:MM:SS)を取得します。 CTime cTime = CTime::GetCurrentTime(); CString time = cTime.Format("%Y/%m/Td %H:%M:%S"); // ファイルパス名からファイル名のみ取得します。 CStringArray items; int pos = 0; CString item; while ((item = file.Tokenize(_T("\\"), pos)) != "") { items.Add(item) } int index = items.GetCount() - 1; CString fileName = items.GetAt(index); // 可変長引数を1つの文字列に整形します。 va_list args; va_start(args, fmt); TCHAR buffer[BUFFER_SIZE + 1]; ZeroMemory(&buffer[0], sizeof(buffer)); _vstprintf(buffer, bufferSize, fmt, args); va_end(args); // 出力するフォーマット文字列に整形します。 CString log; log.Format(_T("%s %s %s(%d) %s\n"), time, fileName, function, line, buffer); return log; }
使用例
Main.cpp
#include "atdafx.h" #include <afxwin.h> #include <Windows.h> int func(int a, int b) { OutDebugString(LOG(_T("a=%d b=%d"), a, b)); int c = a + b; OutDebugString(LOG(_T("c=%d"), c)); return c; } int main(void) { int c = func(1, 2); return 0; }
実行結果
2019/02/22 07:10:15 Main.cpp func(7) a=1 b=2 2019/02/22 07:10:15 Main.cpp func(11) c=3
3. おわりに
ログ出力の際、ログ出力したファイル名、関数名、行番号は必要な情報です。
これが定義済みマクロで取得できるのは便利です。
標準講座MFC6.0―Visual C++による効率的なWindowsプログラミング (Programmer’s SELECTION)
- 作者: ハーバートシルト,田中正造,Herbert Schildt,コスモワークス
- 出版社/メーカー: 翔泳社
- 発売日: 1999/04/01
- メディア: 単行本
- 購入: 11人 クリック: 39回
- この商品を含むブログ (4件) を見る
紹介している一部の記事のコードはGitlabで公開しています。
興味のある方は覗いてみてください。
私が勤務しているニューラルでは、主に組み込み系ソフトの開発を行っております。
弊社製品のハイブリッドOS Bi-OSは高い技術力を評価されており、特に制御系や通信系を得意としています。
私自身はiOSモバイルアプリやウィンドウズアプリを得意としております。
ソフトウェア開発に関して相談などございましたら、お気軽にご連絡ください。
また一緒に働きたい技術者の方も随時募集中です。
興味がありましたらご連絡ください。
EMAIL : info-nr@newral.co.jp / m-futamata@newral.co.jp
TEL : 042-523-3663
FAX : 042-540-1688