Tom's Guide | Tom's Hardware | Tom's Games
![]() |
![]() |
![]() |
Hi,
In vc+ 6, when I try and link all the .obj files together i get:main.obj : error LNK2005: "struct IDirect3DDevice9 * g_pd3dDevice" (?g_pd3dDevice@@3PAUIDirect3DDevice9@@A) already defined in graphics.obj
main.obj : error LNK2005: "struct IDirect3D9 * g_pD3D" (?g_pD3D@@3PAUIDirect3D9@@A) already defined in graphics.obj
main.obj : error LNK2005: "struct tagWNDCLASSEXA g_WCEX" (?g_WCEX@@3UtagWNDCLASSEXA@@A) already defined in graphics.obj
main.obj : error LNK2005: "struct tagMSG g_Msg" (?g_Msg@@3UtagMSG@@A) already defined in graphics.obj
main.obj : error LNK2005: "struct HWND__ * g_hWnd" (?g_hWnd@@3PAUHWND__@@A) already defined in graphics.obj
main.obj : error LNK2005: "struct HINSTANCE__ * g_hInstance" (?g_hInstance@@3PAUHINSTANCE__@@A) already defined in graphics.obj
system.obj : error LNK2005: "struct IDirect3DDevice9 * g_pd3dDevice" (?g_pd3dDevice@@3PAUIDirect3DDevice9@@A) already defined in graphics.obj
system.obj : error LNK2005: "struct IDirect3D9 * g_pD3D" (?g_pD3D@@3PAUIDirect3D9@@A) already defined in graphics.obj
system.obj : error LNK2005: "struct tagWNDCLASSEXA g_WCEX" (?g_WCEX@@3UtagWNDCLASSEXA@@A) already defined in graphics.obj
system.obj : error LNK2005: "struct tagMSG g_Msg" (?g_Msg@@3UtagMSG@@A) already defined in graphics.obj
system.obj : error LNK2005: "struct HWND__ * g_hWnd" (?g_hWnd@@3PAUHWND__@@A) already defined in graphics.obj
system.obj : error LNK2005: "struct HINSTANCE__ * g_hInstance" (?g_hInstance@@3PAUHINSTANCE__@@A) already defined in graphics.obj
Debug/rpg.exe : fatal error LNK1169: one or more multiply defined symbols foundit seems to be defining the global variables multiable times does anyone know how to fix this without the /FORCE option. If need be code can be provided.

The VC++ compiler can incorperate multiple .cpp files into one program, along with libraries. It does this by converting all of the .CPP files into a specially formated bank of assembler (machine) code called an Object File (.OBJ). If you define the same symbol (variable, function, structure, etc.) in more than one .CPP file or library (.LIB, usually) then the linker (which incorperates the .OBJs and .LIBs into one .EXE) will give errors as the one above.
Now that you understand the nature of the problem, here's how you fix it:
First, if you're using custom-made header files, make sure that you're not defining the same variables twice:
--- File HEADER1.H ---
vector<int> v_nNums;
void InitNums();--- File CODE1.CPP ---
#include <vector>
#include <iostream>
using namespace std;#include "HEADER1.h"
int main(){
InitNums();
for(int n = 0; n < v_nNums.size(); n++){
cout<<v_nNums[n]<<endl;
}return 0;
}--- File CODE2.CPP ---
#include <vector>
using namespace std;void InitNums(){
v_nNums.push_back(5);
v_nNums.push_back(3);}
---
This simple example *should* print 5 and 3 on seperate lines, right? But the problem is, you've declared the same variable, 'vector<int> v_nNums', twice. This is because EACH of the .CPP files includes the header, and every time the header is included, you declare the variable. This will cause a linker error as the one you recieved above.
In order to make a variable visible to multiple seperate .CPP files, you need to use the 'extern' keyword. 'extern' is to a variable as a prototype is to a function: It's basically an IOU. This way, you can tell the compiler that the variable exists, and what it is, without declaring it. (Much like you can give the compiler an IOU on functions by defining thier prototypes.) You then need to declare the variable without the 'extern' keyword in ONE and ONLY ONE of the .CPP files.
The code from above SHOULD be changed as follows:
In HEADER1.h, add the 'extern' keyword to the vector's declaration:
--- File HEADER1.H ---
extern vector<int> v_nNums;
void InitNums();--------------------------
In either CODE1.cpp *OR* CODE2.cpp, add this line, somewhere after the headers, and not inside a function or class (global scope):
--- File CODE1.CPP ---
#include <vector>
#include <iostream>
using namespace std;#include "HEADER1.h"
vector<int> v_nNums;
int main(){
InitNums();
/* Rest of code truncated to shorten post*/
---This should enable you to debug your code.
If you're using a premade header, it's a bad one. You could try to repair it yourself, or find another tutorial. I gather you're using D3D... there's plenty of stuff out there.
Oh, two more points:
Personally, I find it helpful to create a .CPP file with the same name as the header file, in this case, HEADER1.CPP, and store all of it's variables there. This saves a lot of time an confusion, esp. on projects longer than 1000 lines.
Second, you can also get this link error if you define a function body in a header file. I can see that's not the case here, but it might come up for people searching this forum. You should always PROTOTYPE functions in headers, NOT define them. For example:
void InitNums();
was a prototype, whereas
void InitNums(){
v_nNums.push_back(5);
v_nNums.push_back(3);}
was a definition. Do the same as above, prototype in headers, and define the function bodies (the code itself) in a .CPP file.
IN SUMMARY:
- Never define variables in headers, always use the 'extern' keyword and define the variable in one and only one CPP file.
- Never define function bodies in header files. Use prototyping, by replacing the brace brackets that contain the code with a single semicolon (';') and then define the function body (the code with brace brackets) in one and only one CPP file.
- Header files are not for code! They are for making CPP files work with each other and libraries only!
I hope that helps you. If you have any trouble with this, feel free to e-mail me, remembering to look carefully at my e-mail address and remove the part after the hyphen (I don't want a load of spam today, thanks.)
Good luck, and happy coding!
-Dave S.

Thank you for your help. I never would realized the problem because it is not possible in java, what im used to using.

![]() |
![]() |
![]() |

This post is quite old and has been locked from receiving new replies. Please create a new posting instead.
| Ads by Google |