I am trying to implement a test project using the Point Cloud Library and OpenCV with multiple files. When I try to compile, I get the "already defined error" message. Probably I'm doing something stupid that cannot realize for some reason - I tried out a couple of solutions found here, none of them seemed to be help in my case.
What I have:
A libs.h file, where I load the lib files (in Project properties, I only set up the .lib paths and load the libs "by hand", like the headers):
#pragma once
#ifndef PCLTEST_LIBS
#define PCLTEST_LIBS
#ifdef _DEBUG
#pragma comment(lib, "pcl_apps-gd.lib")
#pragma comment(lib, "pcl_common-gd.lib")
// a bunch of other debug libs
#else
// the release libs
#endif
#endif
A main file from which I basically deleted everything at this point to debug:
// load the libs
#ifndef PCLTEST_LIBS
#include "libs.h"
#endif
// pcltest includes
// if only this first one is #included, everything is OK
#include "opencvOperations.h"
// #including this one causes the error
#include "files.h"
// these ones are not working also
//#include "cloudOperations.h"
//#include "visualize.h"
// c++ headers
#include <stdio.h>
#include <string>
//#include <sstream>
//#include <iostream>
void writeInfo()
{
// some std::cout calls
}
int main( int argc, char* argv[] )
{
writeInfo();
// this function is in opencvOperations.h and works OK
pcltest::openLena();
}
Then I get several error messages in my main.obj that some (PCL related) symbols are already defined in files.obj. I use PCL related calls both in opencvOperations and files, the first one is OK, the second one does not work.
Edit:
To add more detail, my files.h header:
#pragma once
#ifndef PCLTEST_FILES
#define PCLTEST_FILES
// pcl headers
#ifndef PCL_COMMON_H_
#include <pcl/common/common_headers.h>
#endif
#ifndef PCL_IO_FILE_IO_H_
#include <pcl/io/file_io.h>
#endif
#ifndef PCL_IO_PCD_IO_H_
#include <pcl/io/pcd_io.h>
#endif
#ifndef PCL_IO_PLY_IO_H_
#include <pcl/io/ply_io.h>
#endif
// boost headers
#ifndef BOOST_FILESYSTEM_OPERATIONSX_HPP
#include <boost/filesystem/operations.hpp>
#endif
#endif
namespace pcltest
{
// function to open PCL or binary PLY files
pcl::PointCloud<pcl::PointXYZ>::Ptr openCloud(std::string filename);
// function to save the point cloud to PCD format
void saveCloud();
}
Before splitting the code into separate files, everything worked well (with the same project settings).
Edit2:
I located the source of the problem,
#include <pcl/io/ply_io.h>
causes this. For now, I got rid of everything related to PLY and everything works fine. I'll look at it later, this might be a PCL library specific issue. Still strange to me why this call causes linker error in an other file, where I don't even use PLY related functions/variables.
I had the same problem as you had. I had a surface.h and surface.cpp file, and I found out that I had to include the ply_io.h file from surface.cpp rather than surface.h and now it compiles fine. I hope that helps or makes sense! haha
If a constant is being instantiated in an include one can also use selectany, per http://msdn.microsoft.com/en-us/library/5tkz6s71%28v=vs.80%29.aspx -- in my case:
const int CSdata[] = {1, 2, 3, 4};
when included in more than one source part produces LNK2005 at link time, avoided via:
const __declspec(selectany) int CSdata[] = {1, 2, 3, 4};
Non-portable, yeah ...
Related
While following the book C++ For Dummies, I have three files in my CodeBlocks project, main.cpp, Pen.h, and Pen.cpp. They look like this:
main.cpp:
#include <iostream>
#include "Pen.h"
//#include "Pen.cpp"
using namespace std;
int main()
{
Pen MyPen = Pen();
MyPen.test();
}
Pen.h:
#ifndef PEN_H_INCLUDED
#define PEN_H_INCLUDED
//#include "Pen.cpp" // Uncommenting this gives a different error
using namespace std;
class Pen
{
public:
// attributes omitted
// PROTOTYPES:
// other functions omitted
void test();
};
#endif // PEN_H_INCLUDED
Pen.cpp:
#include <iostream>
#include "Pen.h"
using namespace std;
//other function definitions omitted
void Pen::test()
{
cout << "Test successful." << endl;
}
When I run the code as listed above, I get an "undefined reference to `Pen::test()'" error. To fix this, I changed the #include statements at the top of main.cpp to:
#include <iostream>
//#include "Pen.h"
#include "Pen.cpp"
This works as intended and correctly prints out "Test successful."
My question is this: what in the world is the point of putting a function prototype in a header file if I have to import the .cpp file later on anyways?
EDIT: It turns out this was a problem with not knowing how to use Code::Blocks rather than with the C++ language.
Assuming you're using gcc, you can compile and link in one step by supplying multiple .cpp files via the command line.
g++ Pen.cpp main.cpp
clang should be similar.
clang++ Pen.cpp main.cpp
An #include should never reference a .cpp file. At all. There's no good reason to do it. Include your headers and then supply the names of all .cpp files when you compile. If your project gets big and you have too many .cpp files to reasonably list, then it's time to break out a makefile or similar.
In the main.cpp include the header file:
#include "Pen.h"
The Pen.h file it's ok.
You need to add the Pen.cpp file to the project tree.
Go to Project -> Add files... and add Pen.cpp
Ok so, simply said : I've included a .h into another .h and i get a compilation error telling me that the functions are already defined in main.obj
But, well i've only included Graphics.h one time so how can it be possible that main.obj also defined the Graphics.h functions ?
I got an Error LNK2005 "Already defined in main.obj".
Graphics.h contain functions that many others files will need, but for the moment we have a problem with just one file so I'd like to fix that first.
EDIT : SOLVED by spliting the header, i kept the header for the functions prototypes and I created a new Graphics.cpp for the functions definition
Here are the most concerned files, I've commented the files content so it is readable.
If I'm wrong by commenting please tell me and I'll put it on pastebin or something like that
main.cpp
#include "main.h"
using namespace std;
int main()
{
sMainData data = {};
main_Initialize(data);
while (data.config.window.isOpen())
{
main_Event(data);
main_Update(data);
main_Draw(data);
}
return 0;
}
main.h file :
#ifndef MAIN_H
#define MAIN_H
#include <SFML/Graphics.hpp>
#include "PlayerClass.h"
// Structures...
// Prototypes...
// Functions...
#endif // !MAIN_H
PlayerClass.h file :
#ifndef PLAYERCLASS_H
#define PLAYERCLASS_H
#include "AliveClass.h" // Including the mother
#include <SFML/Graphics.hpp>
#include <iostream>
#include <string>
#include "Graphics.h" // <-- So here we have our man
//Class definition
#endif // !1
Graphics.h file :
#ifndef GRAPHICS_H
#define GRAPHICS_H
#include "SFML/Graphics.hpp"
// Prototypes...
// Functions...
#endif // !GRAPHICS_H
You didn't provide a minimal reproducible example, but my best guess is, you have some function implemented in the header file, while ending up including that header, either directly or indirectly, in more than one cpp file. The result is exactly the same function with exactly the same signature, being compiled in both cpp files, which causes the linker to complain.
Solutions:
Move the function out of the header and into its own cpp file (probably the best)
Find a way to only include the header in one single cpp file (probably the second best in case the header isnt yours and you don't want to touch it)
Make that function inline (probably the easiest, but technically the worst)
I am having trouble tracking down the source of this error because all other Lua appears to be compiling fine.
My scriptManager class is like so:
#include <luabind\lua_include.hpp>
//skip some
LuaScriptManager::LuaScriptManager()
{
state = luaL_newstate(); //is recognised fine
luaL_openlibs(state); //will not compile with this not commented
}
Luabind\lua_include.hpp is like so:
#ifndef LUABIND_CPLUSPLUS_LUA
extern "C"
{
#endif
#include "lua.h"
#include "lauxlib.h"
#include "luaconf.h"
#ifndef LUABIND_CPLUSPLUS_LUA
}
#endif
I don't believe I am missing any #include files that would apply to LuaL_openLibs. However, I didn't set up the lua files for this, someone else on the team did. Does anyone know any potential causes for this, or is my best bet to nuke it and set up the lua include files from scratch?
The following code structure:
ArrayStack.h
#ifndef ARRAY_STACK_H
#define ARRAY_STACK_H
#include "Array.h"
// class ArrayStack
#endif
ArrayStack.cpp
#include "ArrayStack.h"
// ArrayStack's methods
Array.h
#ifndef ARRAY_HEADER
#define ARRAY_HEADER
#include <iostream>
// class Array
#endif
Array.cpp
#include "Array.h"
// Array's methods
main.cpp
#include "ArrayStack.h"
int main() {
return 0;
}
generates these errors:
LNK1169 one or more multiply defined symbols found
LNK2005 _main already defined in Array.obj
What's the problem here? Please do note that Array.cpp did have int main() defined in itself when it was included in the project for the first time, but no longer has it (neither does the ArrayStack.cpp). Also, the code compiles just fine when the int main() in main.cpp is omitted...
The error message means that in all the compiled code, the *.obj files, the linker finds more than one main() function. One is obviously in main.cpp.
The first solution that comes to mind, as mentioned in comments, is to (enforce) re-compile by somehow deleting the *.obj files.
When this doesn't change anything try to rebuild your solution separately from scratch. Start with main.cpp without the include. Then successively add files where you are confident that you won't get errors. Maybe you have to comment out some lines in some cases to make compilation possible.
I've been teaching myself some OpenGL using SFML for creating windows/handling inputs, etc. My main.cpp started getting a bit unwieldy so I decided to start splitting my code up. I created a 4X_vertex.h and a 4X_vertex.cpp (4X is the name of the project) and moved the relevant functions and structs out of my main and into these files. However, when I compile, I get the error
variable or field "drawVertexArray" declared void
which from my research seems to be just an unhelpful message relating to the next error, which is
vertex was not declared in this scope
Here's my list of includes from my main.cpp:
#include <iostream>
#include <fstream>
#include <string>
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include "4x_vertex.h"
#include "4x_constants.h"
My 4X_vertex.h:
#ifndef _4X_VERT_H
#define _4X_VERT_H
struct vertex{
GLfloat x,y,z;
GLfloat r,g,b;
};
void drawVertexArray(vertex v[]);
vertex* loadVertexData();
#include "4X_vertex.cpp"
#endif
The part of 4X_vertex.cpp that's giving me the trouble:
using namespace std;
void drawVertexArray(vertex v[]){
... openGL stuff...
}
All of this worked before I started moving it around so I'm assuming there's something weird going on with the includes, or something. All help is greatly appreciated!
Just some pointers. Best practice is to divide your project up into multiple source files. Typically, you would use the word "main" in the file name of the main source file (if applicable). So you might have something like...
main.cpp
feature1.cpp
feature2.cpp
tools.cpp
For your other files, you will typically name them after the class they implement. You will most often have both a .h and a .cpp. Put your declarations in the .h and your definitions in the .cpp had have the .cpp include the .h. That might give you...
main.cpp
feature1.cpp feature1.h
feature2.cpp feature2.h
tools.cpp tools.h
The modules that reference one of your classes includes it's .h as well. So, main.cpp might look like...
#include <iostream>
#include "feature1.h"
#include "feature2.h"
using namespace std;
void main(int argc, char **argv)
{ ...
cout << "Done!\n";
}
And feature1.cpp might be...
#include "feature1.h"
#include "tools.h"
feature1_class::feature1_class() { ... }
void feature1_class::AUsefulFeature(int val) { ... }
//etc.
...where feature1.h declares the class, defined constants, etc. f.g.,
#ifndef FEATURE1
#define FEATURE1
#include "tools.h"
class feature1_class
{
public:
feature1_class();
void AUsefulFeature(int val);
int APublicMember;
};
#endif
You may have noticed that tools.h is actually include twice in feature1.cpp. It is included from within the feature1.h and explicitly from the .cpp file. If you use the following pattern in your .h files ...
#ifndef TOOLS_H
#define TOOLS_H
//... do your thing
#endif
... then multiple includes shouldn't cause you any problems. And as you refactor code, it is one less thing to have to worry about cleaning up.
If you have been using a single file for all your source up till now, you may have been compiling like so...
cl main.cpp
Which gives you your .exe and .obj and maybe other files. But with multiple source files involved, it isnt much different. You can say...
cl main.cpp feature1.cpp feature2.cpp tools.cpp
There is much more to learn, but this is a start and helps you on the way to better organization of your coding thoughts.
You need to #include "4X_vertex.h" at the top of your 4X_vertex.cpp file. This will allow the .cpp file to see the declaration for the struct vertex.
In general, each file (both .h and .cpp files) needs to #include any header files which contain declarations for items used in that file. This includes the standard headers and OpenGL headers, as well as your custom ones.