外部参照エラーが起きるが何が原因かわからない

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
LisetteLander
記事: 147
登録日時: 15年前
住所: 東京

外部参照エラーが起きるが何が原因かわからない

#1

投稿記事 by LisetteLander » 14年前

キーボード入力用のクラスが外部参照エラーを吐きます
1>------ ビルド開始: プロジェクト: GameProg2, 構成: Release Win32 ------
1> control.cpp
1> main.cpp
1>C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\Platforms\Win32\Microsoft.Cpp.Win32.Targets(268,5): error MSB6006: "link.exe" はコード 1120 を伴って終了しました。
1>control.obj : error LNK2001: 外部シンボル ""private: static int * Ccontrol::Key" (?Key@Ccontrol@@0PAHA)" は未解決です。
1>C:\Documents and Settings\sood\デスクトップ\プログラム\GameProg2\GameProg2\Release\GameProg2.exe : fatal error LNK1120: 外部参照 1 が未解決です。
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========

main.cpp

コード:

#include "player.h"
#include "control.h"

int ProcessLoop(int status){
	if(ScreenFlip()!=0)return -1;
	if(ProcessMessage()!=0)return -1;
	if(ClearDrawScreen()!=0)return -1;
	if(status==99)return-1;
	return 0;
}

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
        ChangeWindowMode(TRUE),SetGraphMode(X_WINDOW,Y_WINDOW,16),DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更と初期化と裏画面設定

		enum{
			START,
			MAINGAME,
			GAMEEND=99
		}GAME_STATUS;
		GAME_STATUS=START;//ゲーム内メインステータス

		Cplayer Player;//ファイル分割前・引越し予定
		Ccontrol Control;//ファイル分割前・引越し予定
		while(ProcessLoop(GAME_STATUS)==0){

				if(Control.gpUpdateKey()!=0)GAME_STATUS=GAMEEND;//呼び出し・引越し予定

				switch(GAME_STATUS){
					case START://引越し予定
						GAME_STATUS=MAINGAME;
						Player.Model_Load("model/モデル.pmd");
						Player.Model_Set_Position(VGet(X_WINDOW/2,Y_WINDOW/2,0));
						Player.Model_Size(1.0f);
						Player.Model_Width(0.00001f);

						break;
					case MAINGAME:
						if(Control.control_input_key(KEY_INPUT_W)>0){
							Player.Mmove_Pos_Ang(MGetTranslate(VGet(0,0,10)));
						}
						Player.Model_Draw();
						break;

					case GAMEEND://終了処理だがprocessloopがやってくれる
						break;

					default:
						break;
				}
		}

		DxLib_End(); // DXライブラリ終了処理
        return 0;
}
↓エラーの発生場所
control.h

コード:

#ifndef DEF_control
#define DEF_control
#include "DxLib.h"
class Ccontrol{
	static int Key[256]; // キーが押されているフレーム数を格納するこれはcontrol.cpp内でしか使わず、共用の変数。
public:
	int gpUpdateKey();
	int control_input_key(int);
	void control_point_mouse(int x,int y);
	void control_point_mouse(int *x,int *y);
};
#endif
control.cpp

コード:

#include "control.h"
int Ccontrol::gpUpdateKey(){
	char tmpKey[256]; // 現在のキーの入力状態を格納する
		GetHitKeyStateAll( tmpKey ); // 全てのキーの入力状態を得る
		for( int i=0; i<256; i++ ){ 
			if( tmpKey[i] != 0 ){ // i番のキーコードに対応するキーが押されていたら
				Key[i]++;     // 加算
			} else {              // 押されていなければ
				Key[i] = 0;   // 0にする
			}
		}
	return 0;
}

int Ccontrol::control_input_key(int input_key){//申請してきたキーの状態を返す。
	return Key[input_key];
}

void Ccontrol::control_point_mouse(int x,int y){//マウスカーソルの位置をセット
	SetMousePoint(x,y);
}

void Ccontrol::control_point_mouse(int *x,int *y){//マウスカーソルの情報を取得
	GetMousePoint(x,y);//ポインタの*無しはアドレスを意味する。
}

YuO
記事: 947
登録日時: 15年前
住所: 東京都世田谷区

Re: 外部参照エラーが起きるが何が原因かわからない

#2

投稿記事 by YuO » 14年前

エラーメッセージの通り,Ccontrol::Keyが定義されていないためのエラーです。

コード:

int Ccontrol::Key[256];
という定義を全翻訳単位中に1つも書いていないのでしょう。
クラスのstaticなメンバ変数は,別途定義が必要です。

というわけで,control.cppにでも先の一行を加えて下さい。

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: 外部参照エラーが起きるが何が原因かわからない

#3

投稿記事 by beatle » 14年前

あまり関係ないですが、Key変数をstaticにするなら、他のメソッドもstaticメソッドにしたほうがいいのではないかと思います。

アバター
LisetteLander
記事: 147
登録日時: 15年前
住所: 東京

Re: 外部参照エラーが起きるが何が原因かわからない

#4

投稿記事 by LisetteLander » 14年前

>YuOさん
ありがとうございます!
解決しました!
以下のようなエラーが出ました・・・
1>control.cpp(2): error C2761: 'int Ccontrol::Key[256]' : メンバー関数の再宣言はできません。
__declspec( selectany )を使えば避けられるようですがVC++特有のコマンドらしいのでできるだけ使いたくないです
どうしたらいいでしょうか?

>beatleさん
確かに、Key変数の後にメソッドが来るので解放されたときにその位置に別のデータが入ってきた場合クラッシュしそうです

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: 外部参照エラーが起きるが何が原因かわからない

#5

投稿記事 by beatle » 14年前

sood さんが書きました:1>control.cpp(2): error C2761: 'int Ccontrol::Key[256]' : メンバー関数の再宣言はできません。
どんなソースコードにしたのでしょうか。Keyはただの配列のはずなのに、「メンバー関数」云々というのは変です。
sood さんが書きました:確かに、Key変数の後にメソッドが来るので解放されたときにその位置に別のデータが入ってきた場合クラッシュしそうです
何を言っているか意味がわかりませんが、多分僕の意図とは違う解釈をされてしまったようです。
配列Keyはプログラム内でただ1つしか存在しないので、int gpUpdateKey();などのメソッドもプログラム内で1つだけ存在するようにしたほうが意味的に正しいと思ったのでした。

アバター
LisetteLander
記事: 147
登録日時: 15年前
住所: 東京

Re: 外部参照エラーが起きるが何が原因かわからない

#6

投稿記事 by LisetteLander » 14年前

こんな感じです。

>beatleさん
なるほど、、

.h

コード:

#ifndef DEF_control
#define DEF_control
#include "DxLib.h"
class Ccontrol{
	int Key[256]; // キーが押されているフレーム数を格納するこれはcontrol.cpp内でしか使わず、共用の変数。
public:
	int gpUpdateKey();
	int control_input_key(int);
	void control_point_mouse(int x,int y);
	void control_point_mouse(int *x,int *y);
};
#endif
.cpp

コード:

#include "control.h"

int Ccontrol::Key[256];

int Ccontrol::gpUpdateKey(){
	char tmpKey[256]; // 現在のキーの入力状態を格納する
		GetHitKeyStateAll( tmpKey ); // 全てのキーの入力状態を得る
		for( int i=0; i<256; i++ ){ 
			if( tmpKey[i] != 0 ){ // i番のキーコードに対応するキーが押されていたら
				Key[i]++;     // 加算
			} else {              // 押されていなければ
				Key[i] = 0;   // 0にする
			}
		}
	return 0;
}

int Ccontrol::control_input_key(int input_key){//申請してきたキーの状態を返す。
	return Key[input_key];
}

void Ccontrol::control_point_mouse(int x,int y){//マウスカーソルの位置をセット
	SetMousePoint(x,y);
}

void Ccontrol::control_point_mouse(int *x,int *y){//マウスカーソルの情報を取得
	GetMousePoint(x,y);//ポインタの*無しはアドレスを意味する。
}

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: 外部参照エラーが起きるが何が原因かわからない

#7

投稿記事 by beatle » 14年前

Keyをstatic変数にしないのならば、グローバル領域で
int Control::Key[256];
を書く必要はありません。というか書いてはいけません。

アバター
LisetteLander
記事: 147
登録日時: 15年前
住所: 東京

Re: 外部参照エラーが起きるが何が原因かわからない

#8

投稿記事 by LisetteLander » 14年前

エラー吐いたのでstaticを外していたのを忘れていました。
ありがとうございます(´・ω・`;)

閉鎖

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