C++ lnk2005 error on two files with extern "C", why? - c++

I have a CPP with extern "C" functions. If they are all in a single file, everything works great. I want to split up the functions into different files just for organizational purpose.
So lets say I have these two files:
File_One.cpp
#pragma once
#include "stdafx.h"
#include <windows.h>
#include "Functions.h"
#include "Variables.h"
#include <string>
#include "File_Two.cpp"
extern "C"
{
__declspec(dllexport) void MethodOne()
{
MethodTwo();
}
}
File_Two.cpp
#pragma once
#include "stdafx.h"
#include <windows.h>
#include "Functions.h"
#include "Variables.h"
#include <string>
extern "C"
{
__declspec(dllexport) void MethodTwo()
{
}
}
I have tried rearranging my include headers in different order, and even place no include headers in file_one.cpp other than the include for file_two.cpp but I always get the same errors.
1) error LNK1169: one or more multiply defined symbols found
2) error LNK2005: _MethodTwo already defined in File_One.obj
What exactly am I doing wrong?
What should I do to fix it?
Thank you!

You're probably running into issues because you're including the File_two.cpp file in your File_one.cpp file. What is happening is that File_two.cpp and File_one.cpp are getting compiled and linked. But because File_two.cpp is included in File_one.cpp, the linker is seeing two copies of MethodTwo, and can't decide which to use.
You should move the declarations to a header:
File_two.h:
extern "C"
{
__declspec(dllexport) void MethodOne()
}
And include that instead.
File_one.h:
extern "C"
{
__declspec(dllexport) void MethodOne();
}
Then define the functions with their body in their respective .cpp files. No need for extern "C" in the source files.

Related

What is `#ifndef FUNCTIONS_H` in functions.h for?

In a header file functions.h, the first two statements are defining FUNCTIONS_H if not already defined. Can someone explain the reason for this action?
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
void print();
int factorial(int);
int multiply(int, int);
#endif
The article you linked isn't about Makefiles at all, it's about compiling multi source file code.
Those are so called include guards. They prevent code from being included unnecessarily multiple times.
If FUNCTIONS_H is not defined then include the content of the file and define this macro. Otherwise, it's defined so file was already included.
There is also #pragma once serving the very same purpose, which although not being in the standard, is supported by many major compilers.
Consider example:
There are also two next header files - func1.h and func2.h. Both have #include "functions.h" inside.
If in main.cpp we do:
#include "func1.h"
#include "func2.h"
// rest of main...
The code will preprocessed to:
#include "functions.h"
// rest of func1.h
#include "functions.h"
// rest of func2.h
// main...
Then:
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
void print();
int factorial(int);
int multiply(int, int);
#endif
// rest of func1.h
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
void print();
int factorial(int);
int multiply(int, int);
#endif
// rest of func2.h
// main...
As you can see if not for include guards, the prototypes for functions would appear for second time. There could be also other crucial things, which redefinition would be causing errors.
It's an "include guard". It prevents redefinition if the header file is #included multiple times.
It's a C++ thing. It has nothing to do with makefiles.

Global variable error C++

I'm having an error I don't know how to fix in my large Operating Systems homework. The error I'm getting is "42 duplicate symbols for architecture x86_64". I presume this is to do with my global variables file "global.h". I have 3 global variables I use and "global.h" is included in an abstract class called "PageReplacementAlgorithm.cpp". I have around 6 classes that are derived from the PageReplacementAlgorithm class and they utilize these global variables. I think the problem comes in when I include all these derived classes in my "main.cpp" as I need to make new instances of them. How can I fix the implementation of the global variables?
Global.h
#include "PageTableEntry.h"
using namespace std;
#ifndef Global_H
#define Global_H
extern PageTableEntry pageTable[64];
extern int* frameTable;
extern int framesCount;
#endif
PageReplacementAlgorithm.h
#include "Global.h"
using namespace std;
#ifndef PageReplacementAlgorithm_H
#define PageReplacementAlgorithm_H
class PageReplacementAlgorithm {
public:
virtual int selectFrame(PageTableEntry &p) = 0;
};
#endif
Example Derived Class (FIFO)
include "PageReplacementAlgorithm.h"
using namespace std;
#ifndef FIFO_H
#define FIFO_H
class FIFO : public PageReplacementAlgorithm {
public:
FIFO();
int selectFrame(PageTableEntry &p);
private:
int entries;
};
#endif
Main.cpp
#include "Aging.cpp"
#include "Clock.cpp"
#include "FIFO.cpp"
#include "MMU.cpp"
#include "NRU.cpp"
#include "Random.cpp"
#include "SecondChance.cpp"
Why do you include all cpp files in main.cpp? I think they contain same includes, right? Even you have the guards there, you do additional includes before that guards and that is probably the source of problems. The main.cpp could contain just main() function and import headers of your classes, there is no need to include cpp.
Also, you can modify your header files to look like this (for sake of extreme safety):
#ifndef PageReplacementAlgorithm_H
#define PageReplacementAlgorithm_H
#include "Global.h"
using namespace std;
...
#endif
I recommend you to look at answer C++ #include guards
If you get rid of #include "(anything).cpp, things should work much better. When you build the project, or run the compiler e.g. g++ main.cpp foo.cpp, that's when those .cpp files get built and linked into your program.

extern "c" behaviour in linux platform

ScriptInterface.h
extern "C"
{
#include "kel.h"
#include "process.h"
#if defined(SIMULATOR_COMPILE_FROM_SCRIPTINTERFACE) || defined(SIMULATOR_WIN)
#include "sigtypes.h"
#endif
}
In windows platform this is not giving any errors(below code)
xyz.cpp
#include "kel.h"
#include "process.h"
#include "sigtypes.h"
#include "ScriptInterface.h"
Whereas it is giving 'Symbol look up error' in Linux platform. Is there any different behavior of extern 'C' in Linux platform?
_Z16KEL_MEM_AllocateP19KEL_MEM_tPoolHandlej is very much a mangled name and it's almost certainly there because you're including kel.h outside of the extern "C" block.
Get rid of the first three includes in xyz.cpp and just use the ones you include from within ScriptInterface.h (which are marked as non-mangling).

Using .c and .cpp files in Visual Studio at the same time

Trying to figure out how to get an application to compile that uses both C and C++ files. Not the entire code, but enough to get the idea:
main.cpp:
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include "one.h"
#include "two.h"
int __stdcall WinMain(HINSTANCE hInst, HINSTANCE hInst2, LPSTR lpCmdLine, int nShowCmd) {
FunctionOne();
FunctionTwo();
}
one.cpp:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <gdiplus.h>
#include <gdiplusflat.h>
using namespace Gdiplus;
using namespace Gdiplus::DllExports;
int FunctionOne() {
}
two.c
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
int FunctionTwo() {
}
The header files contain only definitions for those functions.
Now, if I compile this with a main.cpp, I get an "unresolved external symbol" for FunctionTwo. If I compile this with a main.c, I get the same thing for FunctionOne. Is this even possible, and if so, how would I set up the project to compile properly (Visual Studio 2010)?
It compiles fine if I comment out the alternate function depending on the extension for main.
Thanks!
The problem is two.h, it almost certainly wasn't written to allow a C++ compiler to properly compile the C function prototype. You'll want to take advantage of the predefined __cplusplus macro, like this:
two.h:
#ifdef __cplusplus
extern "C" {
#endif
int FunctionTwo();
// etc...
#ifdef __cplusplus
}
#endif
Lovely macro soup ;) If the header is pre-baked and never saw a C++ compiler before then do this in your .cpp source code file:
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include "one.h"
extern "C" {
#include "two.h"
}
Some programmers name their header files .hpp if they contain C++ declarations and .h if they contain C declarations. That's a pretty good practice I personally favor. So does the Boost team. It didn't otherwise set the world on fire.
C++ does name-mangling to support function overloading while C does not. You will have to mark your function as extern "C" to prevent name mangling.
// main.cpp
extern "C" int FunctionTwo();
.. the rest ..
// two.c
extern "C" int FunctionTwo() {
// stuff
}
See http://www.parashift.com/c++-faq/mixing-c-and-cpp.html for more information on mixing C and C++.

Blitz++ arrays as global arrays

I am working on a project in C++ which has many functions. I don't want to write them in the main program and would like to write a separate .cpp file for each of the functions. Most of these functions will act on some arrays, so I wish to make these arrays global. So I declared all the arrays in a separate .cpp file called globals.cpp and put them in a globals.h file prefixed with extern. The I wrote the functions and the main program as usual, however when I compile, I get an
Here is what I have:
//globals.cpp
#include <iostream>
#include <blitz/blitz.h>
#include <blitz/array.h>
#include "prototype.h"
#include "globals.h"
BZ_USING_NAMESPACE(blitz)
Array<double,2> A(5,5);
In the globals.h file I have
#ifndef GLOBALS_H
#define GLOBALS_H
extern Array<double,2> A(5,5);
#endif
Then I have a function add.cpp, for example
#include <iostream>
#include <blitz/blitz.h>
#include <blitz/array.h>
#include "prototype.h"
#include "globals.h"
BZ_USING_NAMESPACE(blitz)
void add.cpp(){
for(int i=0;i<5;i++){
A(i,i)=i*i;
}
}
I obviously include it in the prototype.h file
#ifndef GLOBALS_H
#define GLOBALS_H
void add();
#endif
Finally I have the main program mainprog.c
#include <iostream>
#include <blitz/blitz.h>
#include <blitz/array.h>
#include "prototype.h"
#include "globals.h"
BZ_USING_NAMESPACE(blitz)
int main(){
add();
cout<<A<<endl;
return 0;
}
However when I compile I get the error `globals.h:6:8: error: ‘Array’ does not name a type
and then an error in the add.cpp function saying the error A was not declared.
How do I declare the blitz arrays as global?
Thank you
`
The issue is that your macro to import the namespace(BZ_USING_NAMESPACE) is below your include of globals.h. Thus the Array class you are trying to reference in globals.h is actually blitz::Array or something at that point.
For a simple fix, simply use the BZ_USING_NAMESPACE in globals.h right above your declaration for A.
Always remember to include everything a header file needs in that header file.
#ifndef GLOBALS_H
#define GLOBALS_H
#include <blitz/blitz.h> //No idea if the Array class needs this header.
#include <blitz/array.h>
BZ_USING_NAMESPACE(blitz)
extern Array<double,2> A(5,5);
#endif