2011-01-15 4 views
3

지난 며칠 동안 필자는 내가 작업해온 CLI 게임 프로젝트의 파일을 연결하는 방법을 알아 내려고 노력했습니다. 프로젝트에는 Client와 Server 코드의 두 부분이 있습니다.(C++) 네임 스페이스로 링크하면 중복 심볼 오류가 발생합니다.

고객은 내가 만든 두 개의 라이브러리가 필요합니다. 첫 번째는 범용 게임 보드입니다. 이것은 GameEngine.h와 GameEngine.cpp 사이에 있습니다. 헤더 파일이

namespace gfdGaming { 

// struct sqr_size { 
//  Index x; 
//  Index y; 
// }; 
    typedef struct { Index x, y; } sqr_size; 
    const sqr_size sPos = {1, 1}; 
    sqr_size sqr(Index x, Index y); 
    sqr_size ePos; 
    class board 
    { 
    // Prototypes/declarations for the class 
    } 
} 

그리고 CPP 파일 같은 것을 그냥 내용 모두를주고 보인다

#include "GameEngine.h" 

type gfdGaming::board::functions 

또한 클라이언트는 선언과 정의로 분할 (이 경우, 사용하여 ticTacToe에서) 게임 고유의 코드가 (TTT.h, Client.cpp). TTT.h는 기본적으로

#include "GameEngine.h" 

#define TTTtar "localhost" 
#define TTTport 2886 

using namespace gfdGaming; 
void* turnHandler(void*); 
namespace nsTicTacToe 
{ 
    GFDCON gfd; 
    const char X = 'X'; 
    const char O = 'O'; 
    string MPhostname, mySID; 
    board TTTboard; 
    bool PlayerIsX = true, isMyTurn; 
    char Player = X, Player2 = O; 

    int recon(string* datHolder = NULL, bool force = false); 
    void initMP(bool create = false, string hn = TTTtar); 
    void init(); 
    bool isTie(); 
    int turnPlayer(Index loc, char lSym = Player); 
    bool checkWin(char sym = Player); 

    int mainloop(); 

    int mainloopMP(); 

}; // NS 
나는 OOP에서 잘 작동하지 않을 것입니다 일부가 있기 때문에 클래스 대신 그룹에 이름 공간에 넣고하기로 결정했습니다

이며, 그것은 나중에 구현하는 것이 훨씬 쉽다 .

이전에 클라이언트를 연결하는 데 문제가 있었지만이 설정이 효과가있는 것으로 보입니다.

또한 내 서버는 Server.h와 Server.cpp의 두 파일로 나뉩니다.

#include "../TicTacToe/TTT.h" // Server needs a full copy of TicTacToe code 

class TTTserv; 
struct TTTachievement_requirement { 
    Index id; 
    Index loc; 
    bool inUse; 
}; 
struct TTTachievement_t { 
    Index id; 
    bool achieved; 
    bool AND, inSameGame; 
    bool inUse; 
    bool (*lHandler)(TTTserv*); 
    char mustBeSym; 
    int mustBePlayer; 
    string name, description; 
    TTTachievement_requirement steps[safearray(8*8)]; 

}; 

class achievement_core_t : public GfdOogleTech { 
public: // May be shifted to private 
    TTTachievement_t list[safearray(8*8)]; 
public: 
    achievement_core_t(); 

    int insert(string name, string d, bool samegame, bool lAnd, int lSteps[8*8], int mbP=0, char mbS=0); 
}; 


struct TTTplayer_t { 
    Index id; 
    bool inUse; 
    string ip, sessionID; 
    char sym; 
    int desc; 
    TTTachievement_t Ding[8*8]; 
}; 
struct TTTgame_t { 
    TTTplayer_t Player[safearray(2)]; 
    TTTplayer_t Spectator; 
    achievement_core_t achievement_core; 
    Index cTurn, players; 
    port_t roomLoc; 
    bool inGame, Xused, Oused, newEvent; 
}; 


class TTTserv : public gSserver { 
    TTTgame_t Game; 
    TTTplayer_t *cPlayer; 

    port_t conPort; 
public: 
    achievement_core_t *achiev; 
    thread threads[8]; 
    int parseit(string tDat, string tsIP); 
    Index conCount; 
    int parseit(string tDat, int tlUser, TTTplayer_t** retval); 

private: 
    int parseProto(string dat, string sIP); 
    int parseProto(string dat, int lUser); 

    int cycleTurn(); 
    void setup(port_t lPort = 0, bool complete = false); 

public: 
    int newEvent; 
    TTTserv(port_t tlPort = TTTport, bool tcomplete = true); 

    TTTplayer_t* userDC(Index id, Index force = false); 
    int sendToPlayers(string dat, bool asMSG = false); 
    int mainLoop(volatile bool *play); 
}; 



// Other 
void* userHandler(void*); 
void* handleUser(void*); 

을 그리고 CPP 파일에 나는 Server.h을 포함 (기본 제공) 및 모든 기능의 내용은 이전에 선언 :

Server.h 정확히 들어 있습니다.

지금 당장의 문제 내 서버를 연결할 때 문제가 있습니다. 더 구체적으로 말하면 nsTicTacToe의 모든 변수에 대해 중복 심볼 오류가 발생합니다 (gfdGaming에서도 가능). 나는를 사용하여 ticTacToe 기능을 필요로하기 때문에, 나는 서버

기본적으로
ld: duplicate symbol nsTicTacToe::PlayerIsX  in Client.o and Server.o 
collect2: ld returned 1 exit status 
Command /Developer/usr/bin/g++-4.2 failed with exit code 1 

It stops once a problem is encountered, but if PlayerIsX is removed/changed temporarily than another variable causes an error 

을 구축 할 때, 내가 더 잘 희망 이러한 오류를 해결하기 위해 내 코드를 구성하는 방법에 대한 조언을 찾고 있어요 (주는()없이) Client.cpp 연결 .

면책 조항 : 내가 너무 많거나 너무 적은 정보를 제공하는 경우 이러한 문제를 해결하기 위해 정적 및 통근자를 사용하여 시도

-I를 올리기 내 처음으로 - 난, 미리 사과 하지만, 그 때문에 분명히 사람들은 당신이 무엇을 내가) =

이 모두를 읽고 응답 할 시간이 걸립니다 누구에게 감사해야 할

+0

헤더 가드를 사용해보십시오. 사용하고 있지 않습니다. – DumbCoder

+1

나는 아래에 답을 주었지만 다른 의견 작성자들이 지적한 것처럼 헤더 가드를 사용한다. – lefticus

+0

그는 머리말을 붙이는 데 어려움을 겪고 있기 때문에 헤더 가드는 사용하지 않는 것보다 항상 사용하는 편이 나을지 모르지만 그의 유일한 문제는 아닙니다. – stnr

답변

6

중복 정의에 대해 오류가 무엇을 얻을 수 없습니다 : 때마다 .cpp 파일 TT 포함 T.h, 글로벌 bool PlayerIsX이 정의됩니다 (nsTicTacToe 네임 스페이스에서는 여전히 글로벌 임). 이 경우에는 Server.cpp와 Client.cpp가 포함됩니다.

이 문제를 해결하는 한 가지 방법은 extern을 사용하여 정의를 선언으로 변경 한 다음 해당 .cpp 파일 (예 : TTT.cpp)에서 실제 정의를 수행하는 것입니다.TTT.h에서

:

namespace nsTicTacToe { 
    ... 
    extern bool PlayerIsX; 
    ... 
} 

TTT.cpp에서 :

다른 정의에 대한
#include "TTT.h" 

bool nsTicTacToe::PlayerIsX; 

등등. 그런데

, 적절한 보호 #ifdef의이 기억 :

#ifndef __TTT_H 
#define __TTT_H 
... header contents 
#endif // __TTT_H 
+0

빠른 응답을 보내 주셔서 감사 드리며 모든 유용한 정보에 대해 감사드립니다. 그게 정확히 내가 필요로하는 것으로 밝혀졌습니다. 완벽하게 작동합니다. – Gfdking

+1

@Gfdking : 문제 없습니다. 그러나 코드 조직 개선에 대한 좌파의 제안 (구조체 또는 클래스 사용)도 권장합니다. – maxelost

1

는 당신이 그것을 자신의 .cpp 파일에 네임 스페이스 nsTicTacToe 부분을 넣어 별도로 컴파일에 연결할 수 또한해야 할 수도 있습니다. 변수의 extern을 선언하고 클라이언트 및 서버 .cpp 파일을 포함하는 헤더 파일.

3

당신은 기본적으로 당신의 전역을 포장 강하게 C++에서 권장되지 않는, 전역을 사용하지만, C.

에서 필요한 경우가 이

당신은 통근 작업을 얻을 수 있지만, "더 나은"대답은 것있다 어떤 종류의 상태 객체.

struct State 
{ 
    GFDCON gfd; 
    const char X; 
    const char O; 
    string MPhostname, mySID; 
    board TTTboard; 
    bool PlayerIsX, isMyTurn; 
    char Player, Player2; 
}; 

메인에 상태 개체를 만들고 게임 시스템의 상태를 알아야하는 각 기능에 전달하십시오.

이렇게하면 장기적으로 코드 조직이 훨씬 향상됩니다.

+0

감사합니다. 그렇습니다. 나는 객체에 데이터를 보유하는 것이 더 좋았을 것이라는 점을 되돌아 보면서 동의합니다. 이 단계에서 코드를 재구성하는 것이 매력적이지는 않지만 분명히 이것을 명심하십시오.) – Gfdking

2

사실, extern은 필요한 것입니다. 아마도 cpp 파일에서 그러한 변수를 정의해야한다는 것을 깨닫거나 기억하지 못할 수도 있습니다.

헤더 :

extern int somevar; 

소스 : 당신이 그 (것)의 사본을 만들고있어 헤더에 전역의 모든 넣어

int somevar = ?; 

어디서나 당신은 당신의 컴파일러가 정확히 무엇을하는 그들을 포함 약 불평.

+1

응답 해 주셔서 감사합니다! 당신 말이 맞아요. extern을 구현하는 방법을 약간 오해 한 것 같습니다. 지금 수정 됨 – Gfdking

관련 문제