複数回定義されます

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
sozai
記事: 57
登録日時: 10年前
住所: 日本-関東
連絡を取る:

複数回定義されます

#1

投稿記事 by sozai » 10年前

現在、複数ファイルでの開発を行っているのですが、以下のようなエラーが出てしまいます。
因みに環境はwindows7のVisualC++ 2010Expressです。

コード:

1>Menu.obj : error LNK2005: "enum <unnamed-type-eScene> eScene" (?eScene@@3W4<unnamed-type-eScene>@@A) は既に game.obj で定義されています。
1>Menu.obj : error LNK2005: "struct Menu_E * Element_Menu" (?Element_Menu@@3PAUMenu_E@@A) は既に game.obj で定義されています。
1>Scene.obj : error LNK2005: "enum <unnamed-type-eScene> eScene" (?eScene@@3W4<unnamed-type-eScene>@@A) は既に game.obj で定義されています。
1>Scene.obj : error LNK2005: "struct Menu_E * Element_Menu" (?Element_Menu@@3PAUMenu_E@@A) は既に game.obj で定義されています。
コードはstruct.h,Menu.cpp,Menu.h,Scene.cpp,Scene.h,Game.cpp,Game.hの七つ分載せておきますが、エラーに無関係と思われる箇所は省略させていただきます。

コード:

//struct.h

#ifndef STRUCT_H
#define STRUCT_H

typedef struct{
	   int  x_M;
	   int  y_M;
	   char element[20]; 
}Menu_E;

Menu_E Element_Menu[3]={
      {80, 100,"Start"},
	{100,150,"Data"},
	{100,200,"Exit"}
};

enum{
    eScene_Menu,
    eScene_Game,
    eScene_Data,
    eScene_End,
}eScene;

#endif

コード:

//Menu.h
extern int i;
extern  int SelectNum;
extern  int Scene;

extern  void Select_D();
extern  void UpdataScene();
extern  void Select_kesan();

コード:

//Menu.cpp
#include "DxLib.h"
#include "struct.h"
#include "Key.h"

int SelectNum;
int i;

void Select_D(){
	for(;i<3;i++){
		DrawFormatString(Element_Menu[i].x_M,Element_Menu[i].y_M,GetColor(255,255,255),Element_Menu[i].element);
	}
}

int Scene = eScene_Menu;

void UpdataScene(){
    if(Element_Menu[0].x_M==80 && Key[ KEY_INPUT_RETURN ]>=1){
	   Scene=eScene_Game;
    }
    if(Element_Menu[1].x_M==80 && Key[ KEY_INPUT_RETURN ]>=1){
	   Scene=eScene_Data;
    }
    if(Element_Menu[2].x_M==80 && Key[ KEY_INPUT_RETURN ]>=1){
	   Scene=eScene_End;
    }
}

void Select_kesan(){
	if(Key[ KEY_INPUT_DOWN ]==1){
		SelectNum = (SelectNum+1)%3;
	}
	if(Key[ KEY_INPUT_UP ]==1){
		SelectNum = (SelectNum+2)%3;
	}
	if(Key[ KEY_INPUT_DOWN ]==1 || Key[ KEY_INPUT_UP ]==1){
		for(;i<3;i++){
			if(i==SelectNum){
				Element_Menu[i].x_M=80;
			}else{
				Element_Menu[i].x_M=100;
			}
		}
	}
}

コード:

//Scene.h
#include "Menu.h"
#include "Data.h"
#include "func.h"


extern void Menu();
extern  void OutWhile();
extern  void GameInWhile();
extern  void Data();
extern  void End();

コード:

//scene.cpp
#include "DxLib.h"
#include "struct.h"
#include "Menu.h"
#include "struct.h"
#include "Data.h"
#include "func.h"


void Menu(){
    Select_kesan();
    Select_D();
}

void OutWhile(){
    LoadG();
    DrawGraph(0,0,Haikei,TRUE);
}

void GameInWhile(){
    The_Func();
    FileInGame();
}

void Data(){
    FileInData();
}

void End(){
    exit(0);
}

コード:

//game.h
#include "Key.h"
#include "Scene.h"
#include "DxLib.h"

コード:

//game.cpp
#include "game.h"

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
    SetMainWindowText("TestApp");
    ChangeWindowMode(TRUE),DxLib_Init(),SetDrawScreen(DX_SCREEN_BACK);
    if(DxLib_Init() == -1)  return -1;

    OutWhile();

    while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && UpdataKey()==0 )
    {
	   if( Key[KEY_INPUT_ESCAPE]==1 || ProcessMessage()!=0 ){
		  break;
	   }
	   switch(Scene){
		  case eScene_Menu:
			 Menu();
			 break;
		  case eScene_Game:
			 GameInWhile();
			 break;
		  case eScene_Data:
			 Data();
			 break;
		  case eScene_End:
			 End();
			 break;
		  default:
			 return -1;
	   }

	  UpdataScene();
    }
    DxLib_End();
    return 0;
}
extern を使っているのは、最初に作り始めたときは関数の内容で分けていたため、変数を複数のファイルで使うことになったからです。
[hr]
Is it true?
Function = a==b;

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 複数回定義されます

#2

投稿記事 by みけCAT » 10年前

ヘッダでElement_Menu変数の実体を宣言しているのは良くないですね。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: 複数回定義されます

#3

投稿記事 by softya(ソフト屋) » 10年前

enum{
eScene_Menu,
eScene_Game,
eScene_Data,
eScene_End,
}eScene;
も実体定義ですね。これもヘッダにあってはいけません。

【補足】
enumに名前を付けるなら、

コード:

enum eScene{
    eScene_Menu,
    eScene_Game,
    eScene_Data,
    eScene_End,
};
とすべきで、これならヘッダに有って問題ありません。
ただし、enum eSceneを使ってくださいね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

sozai
記事: 57
登録日時: 10年前
住所: 日本-関東
連絡を取る:

Re: 複数回定義されます

#4

投稿記事 by sozai » 10年前

お二人の返信を参考にして次のようにしました。
※載せていないコードは変更しなかったため省略しました。

コード:

//struct.h
#ifndef STRUCT_H
#define STRUCT_H

typedef struct{
	   int  x_M;
	   int  y_M;
	   char element[20]; 
}Menu_E;

Menu_E Element_Menu[3];

enum{
    eScene_Menu,
    eScene_Game,
    eScene_Data,
    eScene_End,
};

#endif

コード:

//struct.cpp(新しく追加)
typedef struct{
	   int  x_M;
	   int  y_M;
	   char element[20]; 
}Menu_E;

Menu_E Element_Menu[3]={
     {80, 100,"Start"},
	{100,150,"Data"},
	{100,200,"Exit"}
};


enum{
    eScene_Menu,
    eScene_Game,
    eScene_Data,
    eScene_End,
};

コード:

1>Menu.obj : error LNK2005: "struct Menu_E * Element_Menu" (?Element_Menu@@3PAUMenu_E@@A) は既に game.obj で定義されています。
1>Scene.obj : error LNK2005: "struct Menu_E * Element_Menu" (?Element_Menu@@3PAUMenu_E@@A) は既に game.obj で定義されています。
1>struct.obj : error LNK2005: "struct Menu_E * Element_Menu" (?Element_Menu@@3PAUMenu_E@@A) は既に game.obj で定義されています。
[hr]
Is it true?
Function = a==b;

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 複数回定義されます

#5

投稿記事 by みけCAT » 10年前

struct.hの

コード:

Menu_E Element_Menu[3];
この部分は、どう見ても変数の実体宣言ですね。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

sozai
記事: 57
登録日時: 10年前
住所: 日本-関東
連絡を取る:

Re: 複数回定義されます

#6

投稿記事 by sozai » 10年前

ありがとうございました!
今回のようにヘッダファイルでは実体での宣言をしてしまわぬようきをつけます。
[hr]
Is it true?
Function = a==b;

閉鎖

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