for various reasons I subclassed the std::string like:
class CotengString : public string
{
public:
// Constructors
CotengString();
CotengString(const char* ch) : string(ch) {}
CotengString(const string& str) : string(str) {}
virtual ~CotengString() {};
//Operator"="
CotengString& operator=(const string& str) { return (CotengString&)this->assign(str); }
CotengString& operator=(const char* ch) { return (CotengString&)this->assign(ch); }
};
Inside the DLL I wish to use this code all compiles correctly. But inside my Google Test project I get this error after switching to the subclassed string
LNK2005 "public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(char const *,unsigned int)" (??0?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##QAE#PBDI#Z) already defined in gtest.lib(gtest-all.obj) Devices.Spectro.CppTest <path>\Devices.Spectro.CppTest\Devices.Spectro.Cpp.lib(Devices.Spectro.Cpp.dll)
My gut feeling is that I am missing something obvious. But I don't know what it could be
Okay, then as answer.
First cause
This seems to me to be a problem of multiple includes of header files.
This results in that the compiler wants to compile functions or in this case allocators again and detects "oh I already compiled that!".
So fix would be to add to the header file this:
#ifndef CUSTOM_STRING_IMPLEMENTATION_HEADER
#define CUSTOM_STRING_IMPLEMENTATION_HEADER
....
#endif
Second cause
However, if this isn't the case maybe you're trying to compile this file again in your code which uses the dll which already contains the compiled class.
I personally think it's the second cause according to your log file. There's said that the allocator is already compiled in your library.
Example:
If you're using only header files this results in a big problem. Look here.
Dll code:
SomeHeaderFile.hpp
class NiceClass{
//Constructor is implemented. That causes several problems now!
NiceClass{
}
...
}
Your application code (wich uses the dll):
SomeNiceApplicationCode:
//Linker error now! It's already compiled right into your dll!
#include <SomeHeaderFile.hpp>
int main(){
NiceClass niceClassInstance;
return 0;
}
Solution:
Apply those changes and create and extra cpp file for your class.
Include in your application file only the header file.
class CotengString : public string
{
public:
// Constructors
CotengString();
CotengString(const char* ch) : string(ch); //Use cpp file!
CotengString(const string& str) : string(str); //""
virtual ~CotengString(); //""
//Operator"="
CotengString& operator=(const string& str); //Same for this
CotengString& operator=(const char* ch); //""
};
Related
This question already has answers here:
Function already defined error in C++
(3 answers)
Why aren't my compile guards preventing multiple definition inclusions?
(6 answers)
Closed 2 years ago.
I am trying to build a project using CMake that has the following directory structure
This is the code for the root CMakeLists.txt
include_directories(Steganos PUBLIC ${PROJECT_SOURCE_DIR}/src)
add_executable (
Random_Project_name
${PROJECT_SOURCE_DIR}/src/general/main.cpp
)
add_subdirectory(src/modules/image)
target_link_libraries(Steganos IMAGE_MODULES)
and this is the code for the second CMakeLists.txt stored in src/modules/image:
add_library(
BMP_MODULE OBJECT
"bmp.h"
"bmp/bmp_module.cpp"
"bmp/bmp_decoder.cpp"
"bmp/bmp_encoder.cpp"
)
add_library(
IMAGE_MODULES
$<TARGET_OBJECTS:BMP_MODULE>
)
In bmp.h i have 3 classes declared that i am defining in bmp_decoder/bmp_encoder/bmp_module.cpp and those just include bmp.h
This is the code for bmp.h
#pragma once
#include "general/module.h"
class BMPModule : protected Module {
protected:
//protected functions and variables
public:
BMPModule(const char* bmp_file_path);
~BMPModule();
//public functions
};
class BMPEncoderModule : public BMPModule {
private:
//private variables
public:
BMPEncoderModule(const char* cover_file_path, const char* secret_file_path) : BMPModule(cover_file_path) {
//other initialization
utils::read_byte_stream(/* necessary parameters */);
}
~BMPEncoderModule();
//public functions
};
class BMPDecoderModule : protected BMPModule {
private:
//private variables and functions
public:
BMPDecoderModule(const char* embedded_path) : BMPModule(embedded_path) {
//other initialization
utils::read_byte_stream(/* necessary parameters */);
}
~BMPDecoderModule();
//public functions
};
and this is the code for utils.h
#pragma once
#include <fstream>
enum class error_code {
//random error codes describing what went wrong
};
namespace utils {
//given a pointer to a stream opened in binary mode and a pointer for a byte array,
//reads the byte array and returns how many bytes were read
error_code read_byte_stream(std::ifstream* stream, uint8_t* &byte_stream, uint32_t& stream_size) {
return 1337;
}
}
Well my problem is when i try to build the project i get a linker error telling me that read_byte_stream is already defined in main.cpp.obj
Error LNK2005 "enum error_code __cdecl utils::read_byte_stream(class std::basic_ifstream<char,struct std::char_traits<char> > *,unsigned char * &,unsigned int &)" (?read_byte_stream#utils##YA?AW4error_code##PEAV?$basic_ifstream#DU?$char_traits#D#std###std##AEAPEAEAEAI#Z) already defined in main.cpp.obj ${OUT_FOLDER} ${OUT_FOLDER}\IMAGE_MODULES.lib(bmp_module.cpp.obj)
What am i doing wrong? Should i only have one file associated to bmp.h?(and not 3?) The project builds and runs well if i add inline to read_byte_stream function. Thank you in advance!
When defining functions (or methods) in header files you should mark them as inline so that the linker ignores duplicate copies in multiple translation units:
namespace utils {
//given a pointer to a stream opened in binary mode and a pointer for a byte array,
//reads the byte array and returns how many bytes were read
inline error_code read_byte_stream(std::ifstream* stream, uint8_t* &byte_stream, uint32_t& stream_size) {
return 1337;
}
}
I'm using the bullet 3 physics library, which has the following struct definition inside one of the cpps:
struct btSingleContactCallback : public btBroadphaseAabbCallback
{
btCollisionObject* m_collisionObject;
btCollisionWorld* m_world;
btCollisionWorld::ContactResultCallback& m_resultCallback;
btSingleContactCallback(btCollisionObject* collisionObject, btCollisionWorld* world,btCollisionWorld::ContactResultCallback& resultCallback)
:m_collisionObject(collisionObject),
m_world(world),
m_resultCallback(resultCallback)
{
}
virtual bool process(const btBroadphaseProxy* proxy)
{
btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
if (collisionObject == m_collisionObject)
return true;
//only perform raycast if filterMask matches
if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
{
btCollisionObjectWrapper ob0(0,m_collisionObject->getCollisionShape(),m_collisionObject,m_collisionObject->getWorldTransform(),-1,-1);
btCollisionObjectWrapper ob1(0,collisionObject->getCollisionShape(),collisionObject,collisionObject->getWorldTransform(),-1,-1);
btCollisionAlgorithm* algorithm = m_world->getDispatcher()->findAlgorithm(&ob0,&ob1);
if (algorithm)
{
btBridgedManifoldResult contactPointResult(&ob0,&ob1, m_resultCallback);
//discrete collision detection query
algorithm->processCollision(&ob0,&ob1, m_world->getDispatchInfo(),&contactPointResult);
algorithm->~btCollisionAlgorithm();
m_world->getDispatcher()->freeCollisionAlgorithm(algorithm);
}
}
return true;
}
};
The problem is, the struct is never declared in any of the headers, I need to be able to create an object of this type however. The bullet libraries are statically linked, so I figured I should just be able to declare it myself in my main program as such:
struct btSingleContactCallback
: public btBroadphaseAabbCallback
{
btCollisionObject *m_collisionObject;
btCollisionWorld *m_world;
btCollisionWorld::ContactResultCallback &m_resultCallback;
btSingleContactCallback(btCollisionObject *collisionObject,btCollisionWorld *world,btCollisionWorld::ContactResultCallback &resultCallback);
virtual bool process(const btBroadphaseProxy *proxy);
};
This actually works fine, as long as I'm compiling in debug mode. However, when trying to compile in release mode, I'm getting an unresolved symbol error:
physenvironment.obj : error LNK2001: unresolved external symbol "public: __cdecl btSingleContactCallback::btSingleContactCallback(class btCollisionObject *,class btCollisionWorld *,struct btCollisionWorld::ContactResultCallback &)" (??0btSingleContactCallback##QEAA#PEAVbtCollisionObject##PEAVbtCollisionWorld##AEAUContactResultCallback#2##Z)
Could this have anything to do with c++'s name mangling? Is there a way to avoid it, without having to start making modifications in the library itself?
From a five minute look at the library code, you actually should use ContactResultCallback which is public, letting the implementation of btCollisionWorld::contactTest create and use the private btSingleContactCallback for you.
You did not implement the constructor.
These type of errors are well discussed on SO and many other places, yet, I couldnt find a solution to my particular case.
Basically, I have made a static library project in my solution to seperate some functionality, and reference it in my current project. When I try to call a function from the library, i got this notorious linker error. I think there are no problems in setting up the project (references, dependencies etc.) .
First, I will give some minimal example of what I am working on ( there are some third party classes )
//FileReader.h
class IBKFileReader{
public:
virtual ~IBKFileReader() {} ;
virtual void readFile(std::string fileName, pcl::PointCloud<pcl::PointXYZ>::Ptr pointCloud ) = 0 ;
};
class XYZFileReader : public IBKFileReader
{
public:
virtual void readFile(std::string fileName, pcl::PointCloud<pcl::PointXYZ>::Ptr pointCloud )
{
}
And in my code, I call readFile function on a IBKFileReader object polymorphically.
And, this part is ok, without any errors, it compiles, links and runs.
However, when I move the body of the readFile function to a .cpp file and implement it there
(with the same signature hopefully, i copy pasted) , I got the unresolved external symbol error. This is the header of the function in .cpp file.
void XYZFileReader::readFile(std::string fileName, pcl::PointCloud<pcl::PointXYZ>::Ptr pointCloud )
It seems that implementing the function body inline in the header file, and implementing in some seperate file makes a difference.
What do you think of this issue? Has anybody experienced something similar to this? I hope I am not missing out something obvious.
EDIT:
This is the error log i get:
1>main.obj : error LNK2001: unresolved external symbol "public: virtual void __cdecl XYZFileReader::readFile(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class boost::shared_ptr<class pcl::PointCloud<struct pcl::PointXYZ> >)" (?readFile#XYZFileReader##UEAAXV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##V?$shared_ptr#V?$PointCloud#UPointXYZ#pcl###pcl###boost###Z)
EDIT:
I may have caused some misunderstanding.
FileReader.h and FileReader.cpp is in static library project. I didnt do more than just implementing the function in the cpp file, definitions and such are still there.
In the same solution, in another project I reference to this project.
I am not getting the linker error when compiling the static lib, but when I am using it.
Sorry for my bad English.
A member function that is defined inside its class member list is called an inline member function. Try moving the member definition out of the class definition.
class XYZFileReader : public IBKFileReader
{
public:
virtual void readFile(std::string fileName,
pcl::PointCloud<pcl::PointXYZ>::Ptr pointCloud);
};
void XYZFileReader::readFile(std::string fileName,
pcl::PointCloud<pcl::PointXYZ>::Ptr pointCloud) {}
A lot of years ago i made the mistake to inherit from std::string in DLL and put some funktions like "MakeUpper" to the string. Converting from VS2008 to VS2012 the problem whith the npos pops up. With a workaround from microsoft * i get some other DLLs working, but not DLLs which are used late-binding and have no DLLMain() function.
*Microsoft Workaround
#if _MSC_VER >= 1600
#include <string>
const std::basic_string<char>::size_type std::basic_string<char>::npos = (std::basic_string<char>::size_type) -1;
#endif
The class is declared in a DLL like this:
class MYDLL_API CNyString : public std::string
the errorline is this:
error LNK2001: unresolved external symbol "public: static unsigned int const std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::npos" (?npos#?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##2IB)
Rewriting the MyString class with an std::string as attribute does not work because it is used in several other DLLs where MyString and string functions are mixed a lot, also in function parameters. Example:
void Foo(const CMyString &Param_) ..
...
Foo(std::string("Hallo World")..
Does anyone has an idea how to solve this problem ?
Thanks in advance.
I was getting the following error from Visual Studio:
error LNK2019: unresolved external symbol "public: __thiscall BSTree::BSTreeNode::BSTreeNode(class TestData const &,class BSTree::BSTreeNode *,class BSTree::BSTreeNode *)" (??0BSTreeNode#?$BSTree#VTestData##H##QAE#ABVTestData##PAV01#1#Z) referenced in function "protected: void __thiscall BSTree::insertHelper(class TestData const &,class BSTree::BSTreeNode * &)" (?insertHelper#?$BSTree#VTestData##H##IAEXABVTestData##AAPAVBSTreeNode#1##Z)
Here are the functions that the compiler brings into question:
template < typename DataType, class KeyType >
BSTree<DataType,KeyType>::BSTreeNode::BSTreeNode ( const DataType &nodeDataItem,
BSTreeNode *leftPtr, BSTreeNode *rightPtr ) {
left = leftPtr;
right = rightPtr;
dataItem = nodeDataItem;
}
template < typename DataType, class KeyType >
void BSTree<DataType,KeyType>::insertHelper (const DataType& d, BSTreeNode*& b) {
if (b == 0) {
b = new BSTreeNode(d, 0, 0);
}
else if (d.getKey() < b->dataItem.getKey()) {
insertHelper(d, b->left);
}
else if (d.getKey() > b->dataItem.getKey()) {
insertHelper(d, b->right);
}
else {
b->dataItem = d;
}
}
So I look them over and I believe my code looks correct. So I perform a rebuild and then there are no errors and the program fires up just fine. I asked my lab instructor about why this occurs, but he said that he did not have a suitable answer. This is something that I've seen more and more while my projects are becoming more complex.
I've done some research:
Difference between build, rebuild, and clean solution
Do I always need to Clean/Rebuild?
Is this something that just inevitably happens while working with the Visual Studio IDE? Is there anything that I can do to prevent this? Are there any consequences from having this issue come up (ie. is there a flaw in my code)?
UPDATED: It seems that this might be the cause for much of the linker errors that I've been witnessing the semester.
Here is the advice from a book:
"Compiling programs that use templated classes requires a change in what files are included using the #include preprocessor directive, and in how the program is compiled. Because of how C++ compilers process templated code, the program that creates objects of the classes (e.g., main.cpp) must include the class implementation file, not the class declaration file. That is, it must do #include "Classname.cpp" instead of the usual #include "Classname.h" The rule is in effect the rest of this book. Because the main implementation file does a #include of the class implementation code, the class implementation code is not compiled separately."