ページ 11

宣言の仕方を工夫しようで

Posted: 2009年5月01日(金) 20:52
by NI
初歩的な質問なんですが、龍神録プログラミングの館の5章で変更のあるプログラムを書いて、
ビルドしたんですが、main.cppでエラーが起きました。なぜ起きたのか教えてください。
お願いします。
              main.cppのソース
#define GLOBAL_INSTANCE
#include "../include/GV.h"

//現在のキー入力処理を行う
int GetHitKeyStateAll_2();
//受け取ったキー番号の現在の入力状態を返す
int CheckStateKey(unsigned char Handle);

//データのロード
void load();

//描画メイン
void graph_main();

int img_ch[2][12]; //キャラクタ画像9枚分 X2(変身用)
//キャラクタデータ宣言

//ループで必ず行う3大処理
int ProcessLoop(){
if(ProcessMessage()!=0)return -1;//プロセス処理がエラーなら-1を返す
if(ClearDrawScreen()!=0)return -1;//画面クリア処理がエラーなら-1を返す
GetHitKeyStateAll_2();//現在のキー入力処理を行う
return 0;
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){
ChangeWindowMode(TRUE);//ウィンドウモード
if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化

load();//データロード

while(ProcessLoop()==0){//メインループ

graph_main();//描画メイン

if(CheckStateKey(KEY_INPUT_ESCAPE)==1)break;//エスケープが入力されたらブレイク
ScreenFlip();//裏画面反映
}

DxLib_End();//DXライブラリ終了処理
return 0;
}
このソースで実行すると以下のエラーが出ます。

main.cpp
c:\documents and settings\test\デスクトップ\ゲームプログラミング\project\project\1章\mydat\source\main.cpp(15) : error C2086: 'int img_ch[2][12]' : 再定義されました。

Re:宣言の仕方を工夫しようで

Posted: 2009年5月01日(金) 21:02
by はね
エラー文の通りですが int img_ch がどこか他の場所に書いていませんか?

ちょい編集です。

同じ変数名(この場合は配列ですが)があるとPCはわからなくなります。
なので対処法としてはint img_ch2など名前を変えるか、メンバ変数にするか、
namespaceと使うなどあります。

推測ですが、main.cppのint img_chを消せばいけそうです。

Re:宣言の仕方を工夫しようで

Posted: 2009年5月01日(金) 21:05
by NI
はい。Load.cppとGraph.cppに書いてあります。

Re:宣言の仕方を工夫しようで

Posted: 2009年5月01日(金) 21:07
by pooka
エラーの通りで、int img_ch[2][12]が再定義されています。
5章をみるとGV.hに
GLOBAL int img_ch[2][12];
とあるのでmain.cppの
int img_ch[2][12];
を消してみてください。

Re:宣言の仕方を工夫しようで

Posted: 2009年5月01日(金) 21:12
by NI
> int img_ch[2][12];
> を消してみてください。
実行してみました。そうすると以下のエラーが起きます。main.obj : error LNK2005: "int (* img_ch)[12]" (?img_ch@@3PAY0M@HA) は既に load.obj で定義されています。
graph.obj : error LNK2005: "int (* img_ch)[12]" (?img_ch@@3PAY0M@HA) は既に load.obj で定義されています。
graph.obj : error LNK2005: "struct ch_t ch" (?ch@@3Uch_t@@A) は既に main.obj で定義されています。
LINK : warning LNK4098: defaultlib 'LIBCMT' は他のライブラリの使用と競合しています。/NODEFAULTLIB:library を使用してください。
C:\Documents and Settings\TEST\デスクトップ\ゲームプログラミング\project\project\1章\Debug\RyuJin.exe : fatal error LNK1169: 1 つ以上の複数回定義されているシンボルが見つかりました。

Re:宣言の仕方を工夫しようで

Posted: 2009年5月01日(金) 21:18
by pooka
環境が書かれていませんが、とりあえずリビルドしてみてください。
あとソースコードを記載する時は、規約に則ってプレタグを使うようにしてください。

Re:宣言の仕方を工夫しようで

Posted: 2009年5月01日(金) 21:20
by NI
> 環境が書かれていませんが、とりあえずリビルドしてみてください。
> あとソースコードを記載する時は、規約に則ってプレタグを使うようにしてください。
ソースコードについてはこれから十分気をつけます。
後、リビルドとはなんの事でしょうか?

Re:宣言の仕方を工夫しようで

Posted: 2009年5月01日(金) 21:26
by さが
まず5章を読み直すことからじゃないの?

Re:宣言の仕方を工夫しようで

Posted: 2009年5月01日(金) 21:31
by NI
すでに何回も読み直しました。
もしかしたら
 (後は「main.cpp」「graph.cpp」「load.cpp」にある変数の宣言部と、extern宣言を全て消してください。)
というところが間違っているかもしれません。
変数の宣言部やextern宣言というところがよく分からないので

Re:宣言の仕方を工夫しようで

Posted: 2009年5月01日(金) 21:42
by pooka
コンパイラは何を使用していますか?
Visual C++ならメニューのビルド→ソリューションのリビルドでリビルドできます。

Re:宣言の仕方を工夫しようで

Posted: 2009年5月01日(金) 21:46
by NI
> コンパイラは何を使用していますか?
> Visual C++ならメニューのビルド→ソリューションのリビルドでリビルドできます。
分かりました。やってみます。

Re:宣言の仕方を工夫しようで

Posted: 2009年5月01日(金) 21:48
by NI
やってみましたが、以下のエラーが出ました。
main.obj : error LNK2005: "int (* img_ch)[12]" (?img_ch@@3PAY0M@HA) は既に load.obj で定義されています。
graph.obj : error LNK2005: "int (* img_ch)[12]" (?img_ch@@3PAY0M@HA) は既に load.obj で定義されています。
graph.obj : error LNK2005: "struct ch_t ch" (?ch@@3Uch_t@@A) は既に main.obj で定義されています。
LINK : warning LNK4098: defaultlib 'LIBCMT' は他のライブラリの使用と競合しています。/NODEFAULTLIB:library を使用してください。
C:\Documents and Settings\TEST\デスクトップ\ゲームプログラミング\project\project\1章\Debug\RyuJin.exe : fatal error LNK1169: 1 つ以上の複数回定義されているシンボルが見つかりました。

Re:宣言の仕方を工夫しようで

Posted: 2009年5月01日(金) 21:52
by pooka
じゃあビルド→ソリューションのクリーンを行ってから、再度ビルドしてみてください。

Re:宣言の仕方を工夫しようで

Posted: 2009年5月01日(金) 21:54
by dic
斜め読みですが
extern 絡みでしょう

Re:宣言の仕方を工夫しようで

Posted: 2009年5月01日(金) 21:57
by NI
> じゃあビルド→ソリューションのクリーンを行ってから、再度ビルドしてみてください。
やってみました。前回と同じ結果になりました。

Re:宣言の仕方を工夫しようで

Posted: 2009年5月01日(金) 22:07
by pooka
> はい。Load.cppとGraph.cppに書いてあります。
もしかしてLoad.cppとGraph.cppにも
extern int img_ch[2][12];
って書いてますか?
書いていたら消してみてください。

Re:宣言の仕方を工夫しようで

Posted: 2009年5月01日(金) 22:10
by NI
Load.cppとGraph.cppには
int img_ch[2][12];
と書いてあります。
後、main.cppにもexternは書いていません。

Re:宣言の仕方を工夫しようで

Posted: 2009年5月01日(金) 22:20
by pooka
GV.hに
extern int img_ch[2][12];
と書くだけで他の所には宣言しないようにしてください。
つまり、Load.cpp、Graph.cpp、main.cppはexternを消しただけではなく
int img_ch[2][12];
も書かないようにしてください。

Re:宣言の仕方を工夫しようで

Posted: 2009年5月01日(金) 22:26
by NI
> GV.hに
> extern int img_ch[2][12];
> と書くだけで他の所には宣言しないようにしてください。
> つまり、Load.cpp、Graph.cpp、main.cppはexternを消しただけではなく
> int img_ch[2][12];
> も書かないようにしてください。
>
上記のことを実行してみました。そうすると以下のエラーが起きました。(エラーが二個減りました)
graph.obj : error LNK2005: "struct ch_t ch" (?ch@@3Uch_t@@A) は既に main.obj で定義されています。

C:\Documents and Settings\TEST\デスクトップ\ゲームプログラミング\project\project\1章\Debug\RyuJin.exe : fatal error LNK1169: 1 つ以上の複数回定義されているシンボルが見つかりました。

Re:宣言の仕方を工夫しようで

Posted: 2009年5月01日(金) 22:38
by pooka
5章をもう一度よく読んでみてください。
それと今main.cppはどんな感じになっていますか?
#define GLOBAL_INSTANCE
#include "../include/GV.h"

//ループで必ず行う3大処理
int ProcessLoop(){
	if(ProcessMessage()!=0)return -1;//プロセス処理がエラーなら-1を返す
	if(ClearDrawScreen()!=0)return -1;//画面クリア処理がエラーなら-1を返す
	GetHitKeyStateAll_2();//現在のキー入力処理を行う
	return 0;
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){
	ChangeWindowMode(TRUE);//ウィンドウモード
	if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化

	load();//データロード

	while(ProcessLoop()==0){//メインループ
		
		graph_main();//描画メイン

		if(CheckStateKey(KEY_INPUT_ESCAPE)==1)break;//エスケープが入力されたらブレイク
		ScreenFlip();//裏画面反映
	}

	DxLib_End();//DXライブラリ終了処理
	return 0;
}
main.cppは5章まででこんな感じになると思います。

#すべての章のプロジェクトファイルを一括ダウンロードできるので、その中の5章のファイルと比較したほうが早く解決できるかもしれません。

Re:宣言の仕方を工夫しようで

Posted: 2009年5月01日(金) 22:58
by NI
プロジェクトファイルを一括ダウンロードして、自分が書いたソースと比べて直すことが出来ました。
関わってくださいました皆様、本当にありがとうございました!