「OutputDebugString」って…
VC++には、デバッグを支援するために
デバッグウインドウにテキスト情報を出力する
「OutputDebugString」という関数がある。
これが…今一。(汗)
「printf」などのように何でも食ってくれればいいのだが
文字列しか食ってくれない…。
で、勢いこんな物を作る。
#include <stdio.h>
static void OutputDebugString2( LPSTR format, ... )
{
va_list args;
char buffer[256];
va_start( args, format );
_vsnprintf( buffer, sizeof( Buffer ) - 2, format, args );
*( LPWORD )( buffer + sizeof( buffer ) - 2 ) = 0;
OutputDebugString( buffer );
}
最もこれには、元ネタがある!
「Microsoft Visual Studio」内の「Include」の中にある
「DPRINTF.H」に「static void dprintf(char *format, ...)」が元ネタ。
意外に「Include」の中には、小ネタが入っています。(笑)
でもバグ持ちなのでコイツは、修正したもの。
「_vsnprintf」を使用しているのは、入力された
文字列が長すぎてこの処理自体がバグッて
えらい悩まされたから…。<おばかです…。
2バイトの0は、漢字の先行バイトで切れた場合に備えて。
一応これでバグらないはず…。<一応試した。
で、こんな感じで運用!
#ifdef _DEBUG
#define EE( v ) if( v ){char b[5];itoa(__LINE__,b,10);OutputDebugString("*ERROR:"__FILE__":");OutputDebugString(b);OutputDebugString(":"#v);goto EXIT;}
#else
#define EE( v ) if( v ){goto EXIT;}
#endif
int file_read(char*fname,char**fbuffer,size_t*fsize){
int f=0,r=0,s;
char *b=NULL;
EE((f=open(fname,_O_RDONLY|_O_BINARY,0))==-1);
EE((s=lseek(f,0,2))==0);
EE(lseek(f,0,0)!=0);
EE((b=(char*)malloc(s))==NULL);
EE(read(f,b,s)!=s);
*fbuffer=b;
*fsize=s;
b=NULL;
r=1;
EXIT:
if(b!=NULL)free(b);
if(f>=0)close(f);
/*if(!r)printf("err\n");*/
return r;
}
後処理が共通なので成立・不成立でも
確実に行えるのでミスの軽減が期待できる。
また、処理が停止しない場合でもエラーがアウトプットウインドウに
経過が出力されるので原因の特定がかなり楽になる。
ちなみに「goto EXIT;」を「for(;;);」にすれば、
エラーを出力して処理をストップする。
もし、エラーコードを返すようにしたいのなら…
EE(r=-1,(f=open(fname,_O_RDONLY|_O_BINARY,0))==-1);
なんてのもありかと。
ただエラーコードを一元化すると混乱が少ないけど
一元化するのが難しいし数も膨大になる。
どうしても運用を考えてしまうので
結局単純にエラーを返すようにした。
エラー発生場所は、明確にアウトプットされるしね♪
bool file_read(char*fname,char**fbuffer,size_t*fsize){
int f=0,r=0,s;
char *b=NULL;
EE((f=open(fname,_O_RDONLY|_O_BINARY,0))==-1);
EE((s=lseek(f,0,2))==0);
EE(lseek(f,0,0)!=0);
EE((b=(char*)malloc(s))==NULL);
EE(read(f,b,s)!=s);
*fbuffer=b;
*fsize=s;
close(f);
return true;
EXIT:
if(b!=NULL)free(b);
if(f>=0)close(f);
return false;
}
このマクロでエラーの発生場所が
ダイレクトで表示されるので
デバックがかなり楽になりましたよ♪
| 固定リンク
コメント