インクルードガードマクロって全能じゃないのでしょうか

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

インクルードガードマクロって全能じゃないのでしょうか

#1

投稿記事 by マグロ丼 » 13年前

お世話になります。
アクションゲームのプログラムを組んでいたのですが、ソースコードが長くなったので分割することにしました。
main.cpp player.cpp GV.h struct.h define.h function.h
と言う風に分けていってデバッグしてみたのですが、
エラーで「 1 つ以上の複数回定義されているシンボルが見つかりました。」
と吐き出されてしまいました。
しかしインクルードガードマクロを全部のヘッダファイルに仕込んでいます。
なにとぞ、ご教示願います。

コード:

#ifndef __GV_H__
#define __GV_H__

#include "DxLib.h"
#include "define.h"
#include "math.h"

#ifdef GLOBAL_INSTANCE
#define GLOBAL
#else
#define GLOBAL extern 
#endif

#include "function.h"
#include "struct.h"


//画像用変数宣言部
GLOBAL int image[12];	//キャラクタ画像12枚分
GLOBAL int img_enemy[1];	//敵画像1枚
GLOBAL int image_tama;
GLOBAL char Key[256] ;

//音楽ファイル用変数宣言部
GLOBAL int sound_se[SE_MAX];

//フラグ・ステータス変数
GLOBAL int func_state,stage_count;	//関数制御用変数
GLOBAL int se_flag[SE_MAX];			//サウンドフラグ

//構造体変数宣言部	//キャラクタデータ宣言
GLOBAL enemy_t enemy[ENEMY_MAX];//敵情報

#endif

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

Re: インクルードガードマクロって全能じゃないのでしょうか

#2

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

どちらかと言うとGLOBAL_INSTANCE絡みのミスじゃないでしょうか。
何処かのヘッダでGLOBAL とか書き忘れてませんか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

マグロ丼

Re: インクルードガードマクロって全能じゃないのでしょうか

#3

投稿記事 by マグロ丼 » 13年前

struct.hの中身の関数にもGLOBAL つけてみたらエラーが倍増しました(;´Д`)
お暇なときにでも検分していただけませんか?

よろしくおねがいします。
「main.cpp」

コード:


#define GLOBAL_INSTANCE 

#include"GV.h"



//場面処理用
int function_status;

//カメラ
int camerax=0,cameray=0; 

//キャラクターシート


int image_enemy;

int image_op;
//背景画像
int image_stage;

//発射してからのカウントをする変数。
int counter=0;

//始まった時間
int StartTime;


void op0(){
    DrawGraph( 0 , 0 , image_op , TRUE ) ;//画像を描画
    if(Key[KEY_INPUT_RETURN]==1)           
        function_status=1;}

void main1(){

	int i;
    
    if((GetNowCount() - StartTime) > 60000){    //1ステージの制限時間は6秒
        function_status=2;
    }



    if(ch.attack_flag==1){
        ch.img=image[(ch.x%10)/5+2];
        ch.attack_flag=0;
    }
    if(counter<5)                        //前にエンターを押してから5カウント未満なら              
        counter++;                       //カウントアップ 
    else if( Key[ KEY_INPUT_SPACE]  == 1 ){//5カウント以上たっていたら
        counter=0;//カウンターを戻す

        for(i=0;i<50;i++){
            if(tama[i].flag==0){     //発射していない玉を探し、        
                tama[i].x=ch.x+100;
                tama[i].y=ch.y;
                tama[i].flag=1;  //発射フラグを立てる
                break;
            }
        }                           
    }
    



camerax=ch.x;
 if(camerax<0) camerax=0;
 if(camerax>1280) camerax=1280; 

DrawGraph( -camerax , -cameray ,image_stage, TRUE);//ステージを描画
DrawGraph( ch.x-camerax , ch.y-cameray , ch.img , TRUE ) ;//画像を描画
    
        for(i=0;i<50;i++){
        if(tama[i].flag==1){ //発射している玉なら
            tama[i].x+=5; //xをキャラ位置分増やす 
            DrawGraph( tama[i].x-camerax , tama[i].y-cameray , image_tama , TRUE );//玉を描画
            if(tama[i].x < -32+camerax || tama[i].x > 672+camerax){ //もし画面外まで来たら
                tama[i].flag=0; //発射フラグを戻す
            }
		}

	DrawGraph(en.x, en.y , image_enemy , TRUE ) ;//画像を描画
	
		}
	
        

	if(ch.x>STAGE1_END_X-150)
		function_status=2;
    if(Key[KEY_INPUT_X]==1)           
        function_status=2;
}


void boss(){
	    if((GetNowCount() - StartTime) > 60000){    //1ステージの制限時間は6秒
        function_status=3;
    }
	int White;
	  White   = GetColor( 255 , 255 , 255 ) ; // 白色の値を取得
	if(Key[KEY_INPUT_Z]==1){
      DrawString(0,0, "Zを押せ!" , White);;}           
        function_status=3;

}



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

	image_enemy=LoadGraph("enemy.png");
	image_op=LoadGraph("op.png");
    image_stage = LoadGraph( "stage.png" ) ;//背景の読み込み

    ch.x   =0;
    ch.y   =240;
    ch.muki=3;
    ch.attack_flag;
    ch.walking_flag=0;
   


        if(en.x=640/2,en.y=480)en.flag=0;

	
	StartTime = GetNowCount();
    while(ProcessMessage()==0 && ClearDrawScreen()==0 && !GetHitKeyStateAll(Key) && Key[KEY_INPUT_ESCAPE]==0){
          //↑メッセージ処理          ↑画面をクリア           ↑入力状態を保存       ↑ESCが押されていない       
        switch(function_status){                        
            case 0:
               op0();
                break;
            case 1:
                main1();
				break;
            case 2:
				boss();
                break;
			default:       
                DxLib_End() ;                                // DXライブラリ使用の終了処理                
                return 0;                
                break;        
        }

        ScreenFlip();
    }
 
    DxLib_End();
    return 0;
}

「player.cpp」

コード:

#include "GV.h"

GLOBAL void player(){
    int i;   
    for(i=0;i<50;i++){                  //初期化処理
        tama[i].x=640/2; tama[i].y=480; //座標代入
        tama[i].flag=0;                 //飛んでいない事を示すフラグ=0
    }
    if(ch.x%30==0){         //座標が30で割り切れたら入力可能          
        ch.walking_flag=1;//歩くフラグを立てる。
        
        if( Key[ KEY_INPUT_RIGHT   ]  == 1 )  //→ボタンが押されたら                     
            ch.muki=1;         //右向きフラグを立てる
		else if( Key[ KEY_INPUT_LEFT   ]  == 1 )  //→ボタンが押されたら                     
            ch.muki=2;         //←向きフラグを立てる
        else                                    
            //何のボタンも押されてなかったら
            ch.walking_flag=0; //歩かないフラグを立てる

        if( Key[ KEY_INPUT_SPACE   ]  == 1 )
            ch.attack_flag=1;//攻撃フラグをタテル。    
    }
    if(ch.walking_flag==1){        //歩くフラグが立っていたら    
        if(ch.muki==1){        //→向きならch.x座標を増やす        
			ch.x++;
			ch.img=image[(ch.x%30)/5 +6]; }
		
		else if(ch.muki==2){        //→向きならch.x座標を増やす        
			ch.x--;
		    ch.img=image[(ch.x%30)/5 +6]; }}

    else if(ch.walking_flag==0){
        ch.img=image[(ch.x%30)/2+0];
		       image_tama = LoadGraph("tama.png");
    }
}

問題となっていると疑わしい「struct.h」
「GV.h」の中に入れて使用しているのですが……

コード:

#ifndef __STRUCT_H__
#define __STRUCT_H__

 typedef struct{
        int x,y,img,muki,walking_flag,attack_flag;
}ch_t;
 ch_t ch;//キャラクターの位置


 typedef struct{
        int x,y,
			img,
			muki,
			flag,attack_flag,hp;
}enemy_t;

enemy_t en;
 struct shot{
    int x,y;
    int flag;
};

struct shot tama[50];

#endif
エラーが下記です。
1>player.obj : error LNK2005: "struct shot * tama" (?tama@@3PAUshot@@A) は既に main.obj で定義されています。
1>player.obj : error LNK2005: "struct ch_t ch" (?ch@@3Uch_t@@A) は既に main.obj で定義されています。
1>player.obj : error LNK2005: "struct enemy_t en" (?en@@3Uenemy_t@@A) は既に main.obj で定義されています。
1>C:\Users\maguro\Desktop\leftmyhearts\Debug\leftmyhearts.exe : fatal error LNK1169: 1 つ以上の複数回定義されているシンボルが見つかりました。

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

Re: インクルードガードマクロって全能じゃないのでしょうか

#4

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

softya(ソフト屋) さんが書きました:どちらかと言うとGLOBAL_INSTANCE絡みのミスじゃないでしょうか。
何処かのヘッダでGLOBAL とか書き忘れてませんか?
と書きましたとおり、GLOBALが記述されていません。
どう直されたのかが分かりませんが、次のように書くだけです。

コード:

#ifndef __STRUCT_H__
#define __STRUCT_H__
 
 typedef struct{
        int x,y,img,muki,walking_flag,attack_flag;
}ch_t;
GLOBAL ch_t ch;//キャラクターの位置
 
 
 typedef struct{
        int x,y,
            img,
            muki,
            flag,attack_flag,hp;
}enemy_t;
 
GLOBAL enemy_t en;
 struct shot{
    int x,y;
    int flag;
};
 
GLOBAL struct shot tama[50];
 
#endif
GLOBALの役割に付いてもう一度考えてみてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

マグロ丼

Re: インクルードガードマクロって全能じゃないのでしょうか

#5

投稿記事 by マグロ丼 » 13年前

>>softyaさん
ありがとうございました。
何を勘違いしたのかtypedefの前にGLOBALつけてました。゚(゚´Д`゚)゚。
精進します。本当にありがとうございました。

閉鎖

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