Combine C++ and C - c++

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 recognize extern "C" you have to make this language dependent.
A common way to solve this problem is to bring follwing structure in the header file:
... your include guard of choice
#ifdef __cplusplus
extern "C" {
#endif
//-- your declarations
#ifdef __cplusplus
}
#endif
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":
extern "C" {
#include <My_C_API.h>
}

You have two types of link errors :
Error 86 error LNK2005: _m_deviceContext already defined in main.obj
is because you define m_deviceContext in a header file, and then proceed to include that header file in multiple compilation units (at least in direct3d.cpp, main.c and winstart.c). Move definitions out of header files, and also take care of your include dependencies (main.h and direct3d.h depend on each other - that seems odd).
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
is because you're mixing C and C++ code incorrectly. Either compile everything with a C compiler (or a C++ compiler), or make correct use of extern "C". For more details, check eg. the relevant section of the C++ FAQ Lite.

The error says that something is already defined in main.o.
What you do is put the include before the guards, so no matter what it will include that file possibly creating duplicate code. And you have circular dependencies.
In the file direct3d.h:
#include "main.h"
#ifndef DIRECT3D
#define DIRECT3D
it should be:
#ifndef DIRECT3D
#define DIRECT3D
#include "main.h"
The include in main.c:
#include "main.h"
is a problem because you already include it in direct3d.h which is including main.h.
So the compiler probably goes like:
#include "main.h"
#include "direct3d.h"
#include "main.h" <-- duplicate code detected
throw error.
And there is no problem in mixing C and C++ together.

Related

Unresolved external symbol error, even if function is defined and seen by IDE

using Visual C++ 2008, I am having an "Unresolved external symbol" even if with the IDE I can correctly see both declaration and definition of the function:
The error:
hook_file.obj : error LNK2001: unresolved external symbol "int __cdecl is_directory_objattr(struct _OBJECT_ATTRIBUTES const *)" (?is_directory_objattr##YAHPBU_OBJECT_ATTRIBUTES###Z)
Relevant code in hook_file.cpp:
#include "misc.h"
void handle_new_file(HANDLE file_handle, const OBJECT_ATTRIBUTES *obj)
{
if(is_directory_objattr(obj) == 0 ) {
// etc.
Declaration in misc.h file:
BOOL is_directory_objattr(const OBJECT_ATTRIBUTES *obj);
Definition in misc.cpp file:
#include "misc.h"
BOOL is_directory_objattr(const OBJECT_ATTRIBUTES *obj)
{ //function body here }
I really don't get what the linker has to complain here.
The header with function declaration is included by the file which
calls the function.
The cpp file with the function definition included header file with declaration.
Declaration and definitions are identical.
All files are listed among project files.
Any idea whats wrong?
Thanks!
Have you only include one time your header file?
in misc.h
#ifndef MISC
#define MISC
...
#endif MISC ?

one or more multiply defined symbols found c++

I have a header file and 5 different c++ files and I need this header included in all of my c++ files. I did not declare any cpp files with include "x.cpp" Anyone knows how can I fix this?( I have 6 headers and 5 cpp in total so I did not c/p all the code.)
#ifdef _DEBUG
#ifndef _UTIL_H_
#define _UTIL_H_
int LOOPCOUNTER=0;
int loopi;
#define LOOP LOOPCOUNTER++;
#define MARKLOOPS (loopi=LOOPCOUNTER);
#define PRINTLOOPS cout<<LOOPCOUNTER-loopi;
#define PRINTALLLOOPS cout<<LOOPCOUNTER<<endl;
#endif
#endif
and this is the error message:
1>linkedlistc.obj : error LNK2005: "int loopi" (?loopi##3HA) already defined in arraylistc.obj
1>linkedlistc.obj : error LNK2005: "int LOOPCOUNTER" (?LOOPCOUNTER##3HA) already defined in arraylistc.obj
1>main.obj : error LNK2005: "int loopi" (?loopi##3HA) already defined in arraylistc.obj
1>main.obj : error LNK2005: "int LOOPCOUNTER" (?LOOPCOUNTER##3HA) already defined in arraylistc.obj
1>C:\Users\Eko\Documents\Visual Studio 2010\Projects\mt1\Debug\mt1.exe : fatal error LNK1169: one or more multiply defined symbols found
1>
I think the header file must have only declarations of variables. You should put the definitions to the appropriate cpp file.
Something like this:
// header file
#ifndef _UTIL_H_
#define _UTIL_H_
extern int LOOPCOUNTER;
#endif
// cpp file
// ...
int LOOPCOUNTER = 0;
Assuming you're getting linker complaints about symbols, your problem is probably that your headers get included multiple times. You should not allow that to happen.
The typical solution is to use an include guard like this:
#ifndnef MYHEADER_H
#define MYHEADER_H
//header code here
#endif
This will ensure that your header only actually gets included once.
Also, you should never #include cpp files, only headers.
On the other hand, if include guards do not help, then you have header files which define symbols as opposed to declaring them. Don't do that. See this question for how to handle global data without defining it in headers.

VC++ Error LNK2005 Already Defined In

Hi I'm currently working on a program in C++ and my IDE is obviously VC++ and I came across this linker error.
error LNK2005: "class Graphics TheGraphics" (?TheGraphics##3VGraphics##A) already defined in Game.obj
I looked up how to fix it but none of the links got it fixed. So I thought I ask you all myself.
These are all my files
Game.h
Graphics.h
Inc.h
Main.h
Game.cpp
Graphics.cpp
Main.cpp
WndProc.cpp
and in all of the header files I have the
#ifndef ...
#define...
..
#endif
and I also have some includes in the header files.
in Inc.h I have this between the #ifndef and #define
#include <Windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#include "Game.h"
#include "Graphics.h"
in Main.h I have this between the #ifndef and #define
#include "Inc.h"
and I've also created to objects Game and Graphics objects
extern Game TheGame;
extern Graphics TheGraphics
I've also declared 1 function
LRESULT CALLBACK WndProc(HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam);
That's Main.h
In Game.h and Graphics.h I have this before the #ifndef and #define
#include "Main.h"
and in Game.h I have made a class called Game and a enum called GAMESTATE.
In Graphics.h I have made a class called Graphics.
All the .cpp files for the class only include their class header and WndProc includes Main.h
and after all that I get this when I compile.
1>Graphics.obj : error LNK2005: "class Graphics TheGraphics" (?TheGraphics##3VGraphics##A) already defined in Game.obj
1>Graphics.obj : error LNK2005: "class Game TheGame" (?TheGame##3VGame##A) already defined in Game.obj
1>Main.obj : error LNK2005: "class Graphics TheGraphics" (?TheGraphics##3VGraphics##A) already defined in Game.obj
1>Main.obj : error LNK2005: "class Game TheGame" (?TheGame##3VGame##A) already defined in Game.obj
1>WndProc.obj : error LNK2005: "class Graphics TheGraphics" (?TheGraphics##3VGraphics##A) already defined in Game.obj
1>WndProc.obj : error LNK2005: "class Game TheGame" (?TheGame##3VGame##A) already defined in Game.obj
1>F:\Games\Zombie Lypse\Release\Zombie Lypse.exe : fatal error LNK1169: one or more multiply defined symbols found
please help I've looked everywhere and I've tried to fix it myself. Still nothing.
You have externed the globals everywhere but not defined it anywhere.
extern doesn't define variables. It just tells the compiler that the variable is defined elsewhere. So you have to actually define it elsewhere.
You can do this.
In the header file
/* main.h */
MYEXTERN Game TheGame;
MYEXTERN Graphics TheGraphics
In the first .c file
In main.cpp
/* MYEXTERN doesn't evaluate to anything, so var gets defined here */
#define MYEXTERN
#include "main.h"
In the other .cpp files
/* MYEXTERN evaluates to extern, so var gets externed in all other CPP files */
#define MYEXTERN extern
#include "main.h"
So it gets defined in only one .cpp file & gets externed in all the others.

Common LNK 2019 - function declaration in header file - definition in source file

Considering it's a common issue, what could be the source of this error if one uses this file logic:
Utils.h: declare bool Dummy();
Utils.cpp: define bool Dummy() {return true;}
ClassA.h : an irrelevant class A { bool sheet; public: A(); };
ClassA.cpp: the irrelevant code:
#include "Utils.h"
#include "ClassA.h"
A::A() { sheet = Dummy(); }
Note: all header files contain the guard #pragma once macro.
The error: something like this
Error 2 error LNK2028: unresolved token (0A00000B) "bool __clrcall Dummy(void)"
Error 3 error LNK2019: unresolved external symbol "bool __clrcall Dummy(void)" .... in ClassA.obj
bool __clrcall Dummy(void)
You are compiling the ClassA.cpp file with /clr in effect, generating managed code. Your Dummy() function however was compiled without /clr, making the calling convention __cdecl. The linker notices the discrepancy, it can't find the managed implementation for Dummy.
You must tell the compiler that Utils.cpp was built to native code. Fix ClassA.cpp like this:
#pragma managed(push, off)
#include "Utils.h"
#pragma managed(pop)
#include "ClassA.h"
// etc...

I have no idea what is this(C++ linker error)

getting this
1>main_display.obj : error LNK2005: "struct ALLEGRO_DISPLAY * main_display" (?main_display##3PAUALLEGRO_DISPLAY##A) already defined in event_queue.obj
1>main.obj : error LNK2005: "struct ALLEGRO_DISPLAY * main_display" (?main_display##3PAUALLEGRO_DISPLAY##A) already defined in event_queue.obj
1>main.obj : error LNK2005: "struct ALLEGRO_TIMER * timer" (?timer##3PAUALLEGRO_TIMER##A) already defined in event_queue.obj
1>main.obj : error LNK2005: "struct ALLEGRO_EVENT_QUEUE * event_queue" (?event_queue##3PAUALLEGRO_EVENT_QUEUE##A) already defined in event_queue.obj
1>main_timer.obj : error LNK2005: "struct ALLEGRO_TIMER * timer" (?timer##3PAUALLEGRO_TIMER##A) already defined in event_queue.obj
Any Idea what can cause this?
EDIT:
main_display.h:
#pragma once
#include <allegro5/allegro.h>
#include <stdio.h>
#define SCREEN_W 640
#define SCREEN_H 480
extern ALLEGRO_DISPLAY *main_display = NULL;
void display_init();
void destroy_display();
event_queue.h
#pragma once
#include <stdio.h>
#include <allegro5/allegro.h>
#include "main_timer.h"
#include "main_display.h"
extern ALLEGRO_EVENT_QUEUE *event_queue = NULL;
void event_queue_init();
void event_queue_destroy();
Looks like those structures are defined in a header file. Then they're #included into multiple translation units. You need to make it such that there's only one definition of the particular item.
Given that these are global variables, the way you generally do that is declaring them by marking them extern in the header, and then defining them in some translation unit.
I'm guessing you put function implementations into a header (.h) file without using an inline declaration.
As the header file is included in multiple sources, the body of the function gets compiled multiple times. The linker is complaining about seeing the function more than once.
It looks like you're defining the same struct in different files.
Without actually seeing the files, that's about as far as I get...