デバッグについての質問です DOS窓を出力してそこへ変数などの状態を出力したい

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
七瀬悠

デバッグについての質問です DOS窓を出力してそこへ変数などの状態を出力したい

#1

投稿記事 by 七瀬悠 » 13年前

フォーラム初投稿です。
フォーラムルールは一通り読みましたが盲点などあると思います…。ご容赦くださいm(_ _)m

【質問概要】
コンパイラはVC++2010を使用。LIBはDXライブラリだけです。
デバッグに関する方法でDOS窓を別途出力し、そのDOS窓上へデバッグ中に変数や配列に含まれる値(座標やフラグ用変数など)を表示したいのですが。実行中の変数全てだと情報が多すぎるので指定した変数だけ表示させたいと思っています。
DOS窓を表示させる事は実現しています。DXライブラリ出力ウィンドウとは別で出力しています。こちらのページ(外部サイト)を参考に実装させていただきました。
あとはこのDOS窓へ常時変化する変数などをリアルタイムに覗けるように表示させたいのですがいいようにいきません。
ちなみに上記サイトにも書いてありますがソースファイル(.cpp)が2つあり、mainsource.cpp(DXライブラリウィンドウ出力コード)とmfcconsole.cpp(DOS窓ウィンドウ出力用コード)とに分かれています。前者のmainsourceにはメインプログラムを記述しています。mfcconsole.cppがデバッグ用でDOS窓を出力するようになっています (プロジェクトプロパティでリンカのサブシステムをコンソールに設定しています。これでmfcconsole.cppが動作するようです)


【施策】
具体的なアイデアとして標準関数のprintfを使い変数を指定する方法でいけそうですが、DOS窓に表示されるのは変数の初期値のみで私が行いたいのはこの変数をメインプログラムの処理に合わせて常時変化させたいのです。
例)DOS窓にオブェクトの座標(変数)値出力 -> メインウィンドウのほうでオブジェクトを移動させる・座標が変化 -> DOS窓に出力している座標値を書き換える -> オブジェクト移動 -> 座標値書換 …Loop
DOS窓出力側のソースコードにもメインプログラムと同じコードを書けばそさそうですが同じ処理を2度も書く必要性があるのか?という疑問符が浮かびます…。
…そもそもコンソールウィンドウで変数を扱う事が間違っているのでしょうか?


【問題点】
メインプログラムで計算した座標値などをDOS窓に随時上書き表示するにあたり色々と試しましたが結局更新ができないという結論に至っています。初期値の出力は出来たものの、プログラム開始以降値を変化させる事が出来ない次第です。コンパイラ付属の出力ウィンドウだとダメなのか?というところですが、常に変数などの動的情報を常時閲覧できるウィンドウがあったほうが視覚的にもいいのでDOS窓に変数値を表示させたいと思いました。

以上です。
デバッグに関する事なので少々C言語自体との関連性を疑われるかも分かりませんが、よろしければご教示ください。
よろしくお願いしますm(_ _)m

nil
記事: 428
登録日時: 13年前

Re: デバッグについての質問です DOS窓を出力してそこへ変数などの状態を出力したい

#2

投稿記事 by nil » 13年前

単純に毎フレームprintfしてはどうですか?
七瀬悠さんの書いたコードがどのようなものかがわからないので
うまくいかないのならコードを載せてください

七瀬悠

Re: デバッグについての質問です DOS窓を出力してそこへ変数などの状態を出力したい

#3

投稿記事 by 七瀬悠 » 13年前

涼雅さん返信ありがとうございます^∇^

毎フレームprintfというのはwhile文を使いなよ、という事でしょうか?
やっぱりソースコード載せたほうがいいのでしょうか…

コード:

/* mfcconsole.cpp */
#include "stdafx.h"

#include <stdio.h>
#include <string.h>
#include <windows.h>

extern struct s_int {			// 構造体"s_int"は構造体タグ名
	char index ;		// ラベル用
	int a ;			// オブジェクトの状態を示す(プレイヤー専用)(詳細は別ファイルにて)
	int x ;			// X座標
	int y ;			// Y座標
	int h11 [ 2 ] ;		// オブジェクト当たり判定1(X座標・Y座標) 前方下段
	int h12 [ 2 ] ;		// オブジェクト当たり判定2(X座標・Y座標) 前方中段
	int h13 [ 2 ] ;		// オブジェクト当たり判定3(X座標・Y座標) 前方上段
	int h21 [ 2 ] ;		// オブジェクト当たり判定4(X座標・Y座標) 中心下段
	int h22 [ 2 ] ;		// オブジェクト当たり判定5(X座標・Y座標) 中心中段
	int h23 [ 2 ] ;		// オブジェクト当たり判定6(X座標・Y座標) 中心上段
	int d ;			// オブジェクトの向き(右向き:1・左向き:2・それ以外:0・不明[エラー]:-1)
} ;							// オブジェクト用構造体"s_int" 座標情報などを含む


extern struct s_int iobject ;		// iobject


extern "C"

{
int PASCAL WinMain(HINSTANCE inst,HINSTANCE dumb,LPSTR param,int show);
};


int main(int ac,char *av[])
{
	char buf[256];
	int i;
	HINSTANCE inst;

	inst=(HINSTANCE)GetModuleHandle(NULL);

	buf[0]=0;
	for(i=1; i<ac; i++)
	{
		strcat(buf,av[i]);
		strcat(buf," ");
	}
	
	while( 1 )
	{
		printf ( "%d\r" , iobject.x ) ;
	}

	return WinMain(inst,NULL,buf,SW_SHOWNORMAL);
}

メインプログラムのほうでiobject.xという変数を定義して使用しています。このiobject.xは常に変化していますがこちらでは初期値のまま…というかループ入れると今度はDOS窓しか起動しなくなったのですが
この状態からメインプログラムにジャンプできる方法はありますか?

nil
記事: 428
登録日時: 13年前

Re: デバッグについての質問です DOS窓を出力してそこへ変数などの状態を出力したい

#4

投稿記事 by nil » 13年前

毎フレームとはメインループからフレームごとに呼び出しては?と言う意味です。
while文をメインループの前に入れれば当然メインループに入ることなく無限ループですよね

七瀬悠

Re: デバッグについての質問です DOS窓を出力してそこへ変数などの状態を出力したい

#5

投稿記事 by 七瀬悠 » 13年前

涼雅さん返信ありがとうごいます。

ループについては確かにそうですねw
ですが、メインループがmainsource.cppのほうに書かれており、ここからmfcconsole.cppへジャンプするにはどうすればいいのでしょうか?関数を介してデータを渡しても初期値以降のデータが反映できません。

コード:

/* mainheaderfile.h */
int DebugWindowJSR ( void ) ;

// -----------------------
/* mainsource.cpp */
#include "mainheaderfile.h"
static int DebugPrintfValue = 0 ;		// デバッグ出力値送信用変数
struct s_int {			// 構造体"s_int"は構造体タグ名
	char index ;		// ラベル用
	int a ;			// オブジェクトの状態を示す(プレイヤー専用)(詳細は別ファイルにて)
	int x ;			// X座標
	int y ;			// Y座標
	int h11 [ 2 ] ;		// オブジェクト当たり判定1(X座標・Y座標) 前方下段
	int h12 [ 2 ] ;		// オブジェクト当たり判定2(X座標・Y座標) 前方中段
	int h13 [ 2 ] ;		// オブジェクト当たり判定3(X座標・Y座標) 前方上段
	int h21 [ 2 ] ;		// オブジェクト当たり判定4(X座標・Y座標) 中心下段
	int h22 [ 2 ] ;		// オブジェクト当たり判定5(X座標・Y座標) 中心中段
	int h23 [ 2 ] ;		// オブジェクト当たり判定6(X座標・Y座標) 中心上段
	int d ;			// オブジェクトの向き(右向き:1・左向き:2・それ以外:0・不明[エラー]:-1)
} ;							// オブジェクト用構造体"s_int" 座標情報などを含む
struct s_int iobject ;		// iobject
int WINAPI WinMain ( HINSTANCE hInstance , HINSTANCE hPrevInstance , LPSTR lpCmdLine , int nCmdShow )
{
	ChangeWindowMode ( TRUE ) ;							// ウィンドウモードにする(必須処理)
	SetGraphMode ( 256 , 224 , 16 ) ;							// 画面モードの変更(X:256,Y:240,16bit COLORING)
	
	if ( DxLib_Init () == -1 )
	{
		return -1 ;
	}											// DXライブラリ初期化処理 if文を利用 初期化に失敗したら強制的に終了させる(必須処理)
	
	SetDrawScreen ( DX_SCREEN_BACK ) ;						// 描画先を裏画面に設定(必須処理)
	while ( 1 )
	{
		if ( ProcessMessage () != 0 )
		{
			break ;
		}						// メッセージループ処理 エラー時即座に終了(必須処理)
		
		if ( CheckHitKey (KEY_INPUT_ESCAPE) == 1 )
		{
			break ;
		}						// ESCAPEキーが押されたらループから抜ける(必須処理)
		
		ClearDrawScreen () ;		// 画面の内容を消去する
		
		GetHitKeyHoldAll () ;		// キー入力処理ルーチン
		ScreenFlip () ;			// 裏画面を表画面へ反映(必須処理)

		DebugPrintfValue = iobject.x ;
		DebugWindowJSR () ;		// デバッグ用コンソールへデータを送信するルーチン
	}
	
	DxLib_End () ;			// DXライブラリ終了処理
	
	return 0 ;			// ソフトの終了
}

int DebugWindowJSR ( void )
{
	return DebugPrintfValue ;
}

// --------------------------
/* mfcconsole.cpp */
#include "stdafx.h"

#include <stdio.h>
#include <string.h>
#include <windows.h>

#include "../******(フォルダ名)/mainheaderfile.h"

extern struct s_int {			// 構造体"s_int"は構造体タグ名
	char index ;		// ラベル用
	int a ;			// オブジェクトの状態を示す(プレイヤー専用)(詳細は別ファイルにて)
	int x ;			// X座標
	int y ;			// Y座標
	int h11 [ 2 ] ;		// オブジェクト当たり判定1(X座標・Y座標) 前方下段
	int h12 [ 2 ] ;		// オブジェクト当たり判定2(X座標・Y座標) 前方中段
	int h13 [ 2 ] ;		// オブジェクト当たり判定3(X座標・Y座標) 前方上段
	int h21 [ 2 ] ;		// オブジェクト当たり判定4(X座標・Y座標) 中心下段
	int h22 [ 2 ] ;		// オブジェクト当たり判定5(X座標・Y座標) 中心中段
	int h23 [ 2 ] ;		// オブジェクト当たり判定6(X座標・Y座標) 中心上段
	int d ;			// オブジェクトの向き(右向き:1・左向き:2・それ以外:0・不明[エラー]:-1)
} ;							// オブジェクト用構造体"s_int" 座標情報などを含む


extern struct s_int iobject ;		// iobject


extern "C"

{
int PASCAL WinMain ( HINSTANCE inst , HINSTANCE dumb , LPSTR param , int show ) ;
};


int main( int ac , char * av [ ] )
{
	char buf [ 256 ] ;
	int i ;
	HINSTANCE inst ;

	inst = ( HINSTANCE ) GetModuleHandle ( NULL ) ;

	buf [ 0 ] = 0 ;
	for ( i = 1 ; i < ac ; i ++ )
	{
		strcat ( buf , av [ i ] ) ;
		strcat ( buf , " " ) ;
	}

	printf ( "%d\n" , DebugWindowJSR () ) ;


	return WinMain ( inst , NULL , buf , SW_SHOWNORMAL ) ;
}



本当にメインプログラムにキー入力やキャラクター表示などのコードが書いてあるのですがとりあえず長いので省略しました(多分この問題とは関わりないはず)
これでmfcconsolde.cppのprintfの部分(DebugWindowJSR関数)に値が入っていると思うのですが、表示されているのはやはり初期値のみです。変数そのものをダイレクトに渡す事は出来なかったので関数を介して行ってみたのですがやはりダメですね…。
この変数自体は確実に変化していますので、変数値がおかしいという事ではなさそうです。
やはり問題はDOS窓側をどうやって更新するか、だと思っていますが今ひとつ方法が浮かび上がりません。
ソーヅファイルが違うのでジャンプ命令も使えないですね

non
記事: 1097
登録日時: 14年前

Re: デバッグについての質問です DOS窓を出力してそこへ変数などの状態を出力したい

#6

投稿記事 by non » 13年前

mainsource.cpp 33行からのwhileの中でprintfを使えば、コンソールの方に出力されるのでしょう。
non

七瀬悠

Re: デバッグについての質問です DOS窓を出力してそこへ変数などの状態を出力したい

#7

投稿記事 by 七瀬悠 » 13年前

nonさんありがとうございます。

確かに出力しました。ありがとうございます(゚∀゚)
とりあえず問題は解決したのですが、最後に一つだけ聞かせてください。
printfを指定したのはメインプログラム上なのになぜコンソール上に出力されたのでしょう?
私の想像のつくところではDXライブラリで出力したウィンドウへ情報が出力されると思うのですが…

その辺りよく理解出来ていないのですが、
とりあえずこれでデバッグ作業がかなり効率よく進みそうです。
本当にありがとうございますm(_ _)m

nil
記事: 428
登録日時: 13年前

Re: デバッグについての質問です DOS窓を出力してそこへ変数などの状態を出力したい

#8

投稿記事 by nil » 13年前

DXライブラリによって生成されるウィンドウとコンソールウィンドウは全くの別物です。
printfはコンソールに情報を送信する関数なのでどこから呼びだそうと
コンソールに出力されます

あと、AllocConsole() を使えばもっと簡単にコンソールウィンドウを表示できます。

アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前
住所: 東京
連絡を取る:

Re: デバッグについての質問です DOS窓を出力してそこへ変数などの状態を出力したい

#9

投稿記事 by h2so5 » 13年前

涼雅 さんが書きました: printfはコンソールに情報を送信する関数なのでどこから呼びだそうと
コンソールに出力されます
printfはコンソール固定ではなく標準出力先への出力となります。
デフォルトの出力先はコンソールですが、freopenで標準出力先を変更すればファイルに出力することもできます。

七瀬悠

Re: デバッグについての質問です DOS窓を出力してそこへ変数などの状態を出力したい

#10

投稿記事 by 七瀬悠 » 13年前

涼雅さん、h2so5さんレスありがとうございます。

AllocConsole関数は知っていました。。。実は当掲示板の過去ログに似たような質疑回答があったのでそこからヒントを得ていたのですが、printf標準関数がコンソールに出力するものだとは知りませんでした。我ながら未熟者で申し訳ありません…(´・ω・`)

freopen(フリーオープンで合ってますか?)というのはよく聞きますが新規にウィンドウを開くための関数のようですね。また一つ良い事を聞きました。DXライブラリには元々freopenのような複数ウィンドウ起動のルーチンがないのでこういった問題で引っ掛かっている方も多いのでは?と思います。

頭の中でバラバラになっていたパズルがやっと解けた感じでなんかスッキリしました!
皆様、お忙しいところこんな下等な質問にお答え頂き誠にありがとうございました(^O^)/

non
記事: 1097
登録日時: 14年前

Re: デバッグについての質問です DOS窓を出力してそこへ変数などの状態を出力したい

#11

投稿記事 by non » 13年前

七瀬悠 さんが書きました:freopen(フリーオープンで合ってますか?)というのはよく聞きますが新規にウィンドウを開くための関数のようですね。
私は、エフ・リオープンと読みます。すなわち、現在のストリームを別のものにオープンしなおすものです。
non

ISLe
記事: 2650
登録日時: 14年前
連絡を取る:

Re: デバッグについての質問です DOS窓を出力してそこへ変数などの状態を出力したい

#12

投稿記事 by ISLe » 13年前

OutputDebugStringというWin32 APIを使うとVisual Studioの出力ウィンドウやDebugViewに出力できます。
DebugViewは特定の文字列を含むログに色を付けて目立たせることもできます。

【WindowsSDK】自作TRACE: ISLeのビデオゲーム工房
例えば↑のTRACE関数はprintfのように使えて、コードはデバッグ構成のときだけ生成されてリリース構成では生成されません。

閉鎖

“C言語何でも質問掲示板” へ戻る