LNK2005: already defined in main.obj

This error has made me very frustrated. The error in full is:
1
2
3
4
5
1
1>  main.cpp
1>Server.obj : error LNK2005: "class sf::Packet & __cdecl operator<<(class sf::Packet &,struct NetworkMessage const &)" (??6@YAAAVPacket@sf@@AAV01@ABUNetworkMessage@@@Z) already defined in main.obj
1>Server.obj : error LNK2005: "class sf::Packet & __cdecl operator>>(class sf::Packet &,struct NetworkMessage &)" (??5@YAAAVPacket@sf@@AAV01@AAUNetworkMessage@@@Z) already defined in main.obj
1>C:\Users\David\Documents\Visual Studio 2010\Projects\Kirby_Server\Debug\Kirby_Server.exe : fatal error LNK1169: one or more multiply defined symbols found
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========



It says that some functions i made have already been defined in main.obj, but they are not. They are defined in "NetworkMessage.h". I did some researching and found that a common inducement of this error is including a .cpp when a .h was intended. I have already made sure that all of my includes are .h. All of my files begin with #pragma once . If there is anything i should show you to help you help me just let me know. Here is code i think is relevant:

main.cpp includes
1
2
#include <iostream>
#include "Server.h" 



Server.h includes
1
2
#include "NetworkMessage.h"
#include "ClientStruct.h" 


ClientStruct.h includes
 
#include "Defines.h" 


Defines.h includes
1
2
3
4
5
#include <iostream>
#include <vector>
#include <SFML\Graphics.hpp>
#include <SFML\System.hpp>
#include <SFML\Network.hpp> 


NetworkMessage.h all content(this is where the functions the compiler is complaining about are REALLY defined)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#pragma once

#include "ClientStruct.h"


struct NetworkMessage
{
	Message_Type messageType;
	int integer_Message;
	std::string string_Message;
	ClientStruct clientUpdate_Message;
};

//send
sf::Packet& operator <<(sf::Packet&packet, const NetworkMessage& data)
{
	switch(data.messageType)
	{
	case INT_SIZE_MESSAGE:
	case INT_ID_MESSAGE:
		return packet << data.messageType << data.integer_Message;
		break;
	case STRING_MESSAGE:
		return packet << data.messageType << data.string_Message;
		break;
	case CLIENT_UPDATE_MESSAGE:
		return packet << data.clientUpdate_Message.ID 
			<< data.clientUpdate_Message.ID
			<< data.clientUpdate_Message.position.x
			<< data.clientUpdate_Message.position.y;
	default:
		return packet << 0;
	}
}

//receive
sf::Packet& operator >>(sf::Packet& packet, NetworkMessage& data)
{
	int mT = data.messageType;

	switch(data.messageType)
	{
	case INT_SIZE_MESSAGE:
	case INT_ID_MESSAGE:
		return packet >> mT 
			>> data.integer_Message;
		break;
	case STRING_MESSAGE:
		return packet >> mT 
			>> data.string_Message;
		break;
	case CLIENT_UPDATE_MESSAGE:
		return packet >> mT 
			>> data.clientUpdate_Message.ID 
			>> data.clientUpdate_Message.isWDown 
			>> data.clientUpdate_Message.isADown 
			>> data.clientUpdate_Message.isSDown 
			>> data.clientUpdate_Message.isDDown;
	default:
		return packet >> mT;
	}
}


networkmessage.h appears to be included in both main.cpp and server.cpp.
Now if networkmessage.h werte a pure header file containing only declarations, that wouldn't be a problem.

However,
 
sf::Packet& operator <<(sf::Packet&packet, const NetworkMessage& data)

 
sf::Packet& operator >>(sf::Packet& packet, NetworkMessage& data)

are implementations, not delcarations. Therefore, they are getting included in main.obj and server.obj. This is what the linker is complaining about.
#pragma once avoids the problem of recursive inclusion, but the header is included once in every source file leading to multiple definitions.
There are three ways to fix the error:

1. Place only the declarations in NetworkMessage.h and move the definitions to NetworkMessage.cpp (recommended)

2. Specify internal linkage for the functions
1
2
3
4
5
6
7
8
9
10
// send
static sf::Packet& operator <<(sf::Packet&packet, const NetworkMessage& data)
{
    // ....
}
//receive
static sf::Packet& operator >>(sf::Packet& packet, NetworkMessage& data)
{
    // ....
}


3. Make them inline functions (not recommended)
1
2
3
4
5
6
7
8
9
10
// send
inline sf::Packet& operator <<(sf::Packet&packet, const NetworkMessage& data)
{
    // ....
}
//receive
inline sf::Packet& operator >>(sf::Packet& packet, NetworkMessage& data)
{
    // ....
}
Topic archived. No new replies allowed.