I was trying to do a DirectX tutorial, but I wanted to write the application in C and not in C++. So I wrote the code in C, but when I tried to compile it I got lot’s of errors on the “setupD3D” function. So I just renamed a file to .cpp. But the new code didn’t compile either. I think that combining C and C++ is the problem, or there are to many cross-references. Can anyone tell me what the problem is in this code?
direct3d.h:
#include "main.h"
#ifndef DIRECT3D
#define DIRECT3D
int m_videoCardMemory;
char m_videoCardDescription[128];
ID3D11DeviceContext* m_deviceContext = 0;
D3DXMATRIX m_projectionMatrix;
D3DXMATRIX m_worldMatrix;
D3DXMATRIX m_orthoMatrix;
int setupD3D(BYTE vsync, HWND hwnd, float screenDepth, float screenNear);
void terminateD3D();
void beginScene(float red, float green, float blue, float alpha);
void endScene();
#endif
direct3d.cpp
#include "direct3d.h"
// code
main.h:
#ifndef MAIN_FUNC
#define MAIN_FUNC
#pragma comment(lib, "dxgi.lib")
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "d3dx11.lib")
#pragma comment(lib, "d3dx10.lib")
#include <Windows.h>
#include <dxgi.h>
#include <d3dcommon.h>
#include <d3d11.h>
#include <d3dx10math.h>
#include "direct3d.h"
int breedte, hoogte;
LRESULT CALLBACK Actie(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
void main_loop(MSG* msg);
void keyevent();
#endif
main.c
#include "main.h"
// code
winstart.c
#include "main.h"
// code
Errors:
Error 86 error LNK2005: _m_deviceContext already defined in main.obj
Error 87 error LNK2019: unresolved external symbol _setupD3D referenced in function _Actie@16
Error 88 error LNK2019: unresolved external symbol _terminateD3D referenced in function _Actie@16
Error 89 error LNK2019: unresolved external symbol _beginScene referenced in function _render
Error 90 error LNK2019: unresolved external symbol _endScene referenced in function _render
Error 91 error LNK1120: 4 unresolved externals
I also have 84 warnings about macro redefinitions.
If you declare functions in a .cpp file the compiler will compile it as C++ code (no matter if it’s pure C or not). Unfortunately C++ has a mechanism called Name mangling which allows for example overloading of functions while C doesn’t. If you now want to call such a function fro a .c file (which is recognized as pure C by the compiler) the compiler is creating references for another naming of the symbols (functions in your case) than they exist and the linker is not able to match them anymore.
To solve this, you can put an
extern "C"in front of every function you want to be callable by C. As C does not recognizeextern "C"you have to make this language dependent.A common way to solve this problem is to bring follwing structure in the header file:
This instructs the C++ compiler to create names that are C compliant. As the C compiler does not provide the preprocessor symbol “__cplusplus” it ignores the extern statement. (Which is ok as the C compiler always only creates C compliant symbol names)
Instead of changing header files (sometimes you are not allowed to) it’s also legal to include a whole header file embraced by
extern "C":