2

So I have this dll that holds some functions for my program. Called gc.dll I have it as a reference in my main project. In my main project I have 2 headers and 2 source files,

dx9d3d.h
main.h


main.cpp
dx9d3d.h

Heres my includes on each file

dx9d3d.h:
#include "gc.h"


dx9d3d.cpp:
#include "dx9d3d.h"

main.h:
#include <Windows.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string>
#include "basics.h"
#include "dx9d3d.h"

main.cpp:
#include "main.h"

I keep getting the linker error for multi defined symbols for the d3ddevice and directx symbols I have in my gc.h. I have no idea how I can include gc.h to dx9d3d.h without it being a multi defined symbol :/ please help im kindof a noob to these linker errors.

and heres the code inside gc.h

namespace xaD3D {
__declspec(dllexport) LPDIRECT3D9 d3d;
__declspec(dllexport) LPDIRECT3DDEVICE9 d3dDev;
    __declspec(dllexport) bool initD3D(HWND hWnd);
}

and heres the errors

2>main.obj : error LNK2005: "struct IDirect3DDevice9 * xaD3D::d3dDev" (?                     d3dDev@xaD3D@@3PAUIDirect3DDevice9@@A) already defined in dx9d3d.obj
2>main.obj : error LNK2005: "struct IDirect3D9 * xaD3D::d3d" (?     d3d@xaD3D@@3PAUIDirect3D9@@A) already defined in dx9d3d.obj  
Ethan Shulman
  • 43
  • 1
  • 4
  • what is inside gc.h and dx9d3d.h? -- the answer is likely to be there. – Soren Jul 29 '11 at 21:56
  • 2
    Please show us the exact error message(s), and include the code where you define these objects. Header files usually declare objects, not define them, so they're usually unimportant in diagnosing linker errors. – David Thornley Jul 29 '11 at 21:58

2 Answers2

1

Usually multiple include errors are solved in c++ by this type of construct:

#ifndef GC_Header
#define GC_Header
//header code enclosed here
#endif //GC_Header

Try adding these instructions at the beginning and at the end of the gc.h header file. Your gc.h file should look like this:

#ifndef GC_Header
#define GC_Header

namespace xaD3D {
__declspec(dllexport) LPDIRECT3D9 d3d;
__declspec(dllexport) LPDIRECT3DDEVICE9 d3dDev;
    __declspec(dllexport) bool initD3D(HWND hWnd);
}
#endif //GC_Header

HTH,
JP

Ioan Paul Pirau
  • 2,733
  • 2
  • 23
  • 26
  • Good suggestion, and he should do that regardless, however it does not look like he include the header files multiple times. – Soren Jul 29 '11 at 22:15
  • "#pragma once" could also be used as it's supported by most compilers these days(I actually do not have knowledge of one which does not support it) – celavek Jul 29 '11 at 22:37
  • @celavek true.. but [`#pragma once`](http://en.wikipedia.org/wiki/Pragma_once) is non-standard, that's why I suggested [`include guards`](http://en.wikipedia.org/wiki/Include_guard) – Ioan Paul Pirau Jul 29 '11 at 22:42
  • indeed it's not. But I was not implying that in any way :), I was saying it's an alternative which indeed behaves in implementation defined ways; good details at the following link http://stackoverflow.com/questions/4563356/did-pragma-once-make-it-into-c0x – celavek Jul 29 '11 at 22:46
  • basics.h is not linked to gc.h and my code now looks like this and it doesnt work #ifndef gc_h #define gc_h __declspec(dllexport) void mbA(string text); __declspec(dllexport) void mbB(string text); __declspec(dllexport) void mbC(string text); namespace xaD3D { __declspec(dllexport) LPDIRECT3D9 d3d; __declspec(dllexport) LPDIRECT3DDEVICE9 d3dDev; __declspec(dllexport) bool initD3D(HWND hWnd); } #endif – Ethan Shulman Jul 29 '11 at 23:22
1

The problem is occurring because the project contains main.cpp and dx9d3d.cpp, both of which include dx9d3d.h, which includes gc.h, so gc.h gets included twice in total, and therefore xaD3D gets defined twice.

As @John Paul said, the usual solution is to wrap the definition in #ifndef/#endif:

#ifndef GC_H
#define GC_H
...
#endif

An alternative is to use #pragma once (if supported) in the header file.

MRAB
  • 20,356
  • 6
  • 40
  • 33
  • Wouldn't he more effectively solve the problem by moving code definition into the .cpp? – Soren Jul 29 '11 at 22:30