kkamegawaの購入記録

漫画、小説、映画や買ったものの記録をつらつらしていきます。昔は一部技術情報もありました…

OutputDebugString()の出力をもらう

 Win32 APIにはOutputDebugString()という関数が提供されています。これは、VC6.0では「デバッグ」タブにプログラムから任意の文字列を出力させることができます。しかし、Cランタイムで言うところのprintf()のように、書式制御はありません。基本的にはみんなマクロや制御文字を追加する関数を使っているようです(私も自作で使っています)。

 この文字列はデバッガでしかとれないのでしょうか?そんなことはありません。Plathome SDKにdbmonというサンプルがあり、結構簡単にとってます。エッセンスだけ抜き出してみます。これだけだと単なるコンソールへの出力になりますが、適宜ファイルへの書き込みをしてみるとか(私はこれ)、ネットワークへリダイレクトして、そっちででっかいバッファ用意して、貯めたあとファイルへ書き込むとかいろいろ応用が広がると思います。特にゲームなんかでできるだけローカルPCに負担をかけたくない場合とかいいですね。

 実は、伊原さんの日記 Device\PhysicalMemory オブジェクトを読んで、え、Windows Server 2003 SP1でdbmon(私はdblogと改名&機能改良して使ってますが)動かなくなるかな?と思ってソースを見直したのでした(^^;(いや、大丈夫だとは思ってましたけど)。

HANDLE hAckEvent, hReadyEvent, hSharedFile;

LPVOID pSharedMem;

LPSTR pString;

DWORD ret, dwBuf;

LPDWORD pThisPid;

TCHAR tszTempBuffer[1024];

SECURITY_ATTRIBUTES sa;

SECURITY_DESCRIPTOR sd;

// セキュリティの初期化

InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);

SetSecurityDescriptorDacl(&sd, TRUE, (PACL)NULL, FALSE);

// OutputDebugStringで書き込んだよーというイベントを取得するためにイベント作成。

hAckEvent = CreateEvent(&sa, FALSE, FALSE, "DBWIN_BUFFER_READY");

hReadyEvent = CreateEvent(&sa, FALSE, FALSE, "DBWIN_DATA_READY");

// OutputDebugString()で書き込まれるバッファを共有メモリで開く

hSharedFile = CreateFileMapping((HANDLE)-1, &sa, PAGE_READWRITE, 0, 4096, "DBWIN_BUFFER");

pSharedMem = MapViewOfFile(hSharedFile, FILE_MAP_READ, 0, 0, 512);

pString = (LPSTR)pSharedMem + sizeof(DWORD);

pThisPid = (LPDWORD)pSharedMem;

SetEvent(hAckEvent); // 準備完了まで待つ

for (;;) {

ret = WaitForSingleObject(hReadyEvent, INFINITE);

if (ret == WAIT_OBJECT_0) {

lstrcpyn(tszTempBuffer, pString);

printf("%s", pString);

SetEvent(hAckEvent);

}

}