在過去的幾天裏,我一直在試圖弄清楚如何鏈接我一直在研究的CLI遊戲項目的文件。有兩個項目,客戶端和服務器代碼。(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
客戶端還具有特定的遊戲代碼(在這種情況下,井字遊戲)分成聲明和定義(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。
Server.h正好包含:
#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並提供main()和先前聲明的所有功能的內容。
現在手頭的問題 我在連接我的服務器時遇到問題。更具體地說,我在nsTicTacToe(也可能在gfdGaming中)爲每個變量都得到了一個重複的符號錯誤。因爲我需要井字遊戲功能,我鏈接Client.cpp(無主())建立服務器
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
本質的時候,我正在尋找如何更好地組織我的代碼,希望能夠修正這些錯誤的任何建議。
免責聲明: 如果我提供過多或過少的信息 - 我提前道歉,因爲這是我第一次發佈
-I使用靜態和extern解決這些問題都試過了,但顯然這些都不是我所需要的
謝謝你的人誰花時間閱讀這一切和應對=)
嘗試使用標頭警衛,你沒有使用任何。 – DumbCoder
我在下面提供了一個答案,但也使用標頭守衛,正如其他評論者指出的那樣。 – lefticus
因爲他有鏈接的問題,頭衛兵可能不是他唯一的問題,雖然使用它們總是比我更好(我認爲?)比不使用。 – stnr