Unresolved external symbol on non-inline function body - c++

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) {}

Related

Unresolved external when just adding an incomplete type in class in header

I don't understand why the linker says it can't find this function when I add something to my class.
// In .h file
class Importer
{public:
void importOBJFile();
}
// In .cpp file
// INCLUDE ALL THE ASSIMP LIBRARY HEADERS HERE
void Importer::importOBJFile()
{
Assimp::Importer importerInst;
const aiScene* scene = importerInst.ReadFile("filename", aiProcess_Triangulate);
}
Everything works fine like this. However if I add:
const class aiScene* scene = nullptr;
... to my class definition, or forward declare class aiScene; and then just add:
const aiScene* scene = nullptr;
... to my class definition, then I get an error compiling:
Error LNK2019 unresolved external symbol "public: class aiScene const
__cdecl Assimp::Importer::ReadFile(char const *,unsigned int)" (?ReadFile#Importer#Assimp##QEAAPEBVaiScene##PEBDI#Z) referenced in
function "public: class aiScene const * __cdecl
Assimp::Importer::ReadFile(class std::basic_string<char,struct
std::char_traits,class std::allocator > const &,unsigned
int)"
(?ReadFile#Importer#Assimp##QEAAPEBVaiScene##AEBV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##I#Z)
Why is it complaining that it can't find the readFile function when I just forward declare aiScene class and add a pointer declaration to the class definition?
Pasting all the Assimp library headers in the .h file before my Importer class fixes this, but I wanted to avoid pasting headers in headers, and I can't understand why this is happening.
I am on Visual Studio 2019
I found the problem. The problem is that Visual Studio for some reason doesn't allow you to forward declare a class as a struct and vice versa. Not sure why this is the case. I asked a question about this previously, other compilers don't see class and struct as different for this purpose.

Forward-declare struct which only has definition in a library cpp

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.

Passing C++ vector to method results in unresolved externals

I've looked at a ton of examples and I don't know what I'm doing wrong. I can't pass a vector as a parameter or the compiler says unresolved externals.
Here's an example that doesn't work for me:
In the .h:
#include <vector>
void VectorTest(std::vector<std::string> & vect);
In the .cpp:
void VectorTest(std::vector<std::string> & vect)
{
}
Also in the .cpp, in a method where I'm trying to call it:
std::vector<std::string> test;
VectorTest(test);
When I compile I get the error:
error LNK1120: 1 unresolved externals
If I comment out
VectorTest(test);
It builds. I'm still learning C++ so it's probably something obvious. I'm using Visual Studio Express 2013 if that matters.
On a Yahoo! Answers someone posted this example and it does not work for me, same error:
void myfunc( std::vector<int>& vec )
{
}
std::vector<int> vec;
myfunc( vec );
Here's the error (trying to use the myfunc shown above):
error LNK2019: unresolved external symbol "public: void __thiscall trackManager::myfunc(class std::vector<int,class std::allocator<int> > &)" (?myfunc#trackManager##QAEXAAV?$vector#HV?$allocator#H#std###std###Z) referenced in function "public: __thiscall trackManager::trackManager(void)" (??0trackManager##QAE#XZ)
It looks like you declared VectorTest() as a trackManager member function in the header but then defined it as a free function in the cpp. This results in two unrelated functions with the same name. If you try to call VectorTest() without qualifications from inside a trackManager member function, the resolver will (sensibly) prefer the version that is also a trackManager member over the free function. But since that one doesn't have a definition, the linker can't figure out what to do with it and you get an error.
To fix this, either move the declaration out of the body of trackManager (if you want it to be a free function), or write the definition as void trackManager::VectorTest(...) (if you want it to be a member).
You're most likely missing the include file for string. Try to add the following line at the top of the .h file:
#include <string>

global template objects c++

i have a class
class ICIecHdlcSetup
{
//some thing
};
to create a global access object i do this:
//in obj.cpp:
ICIecHdlcSetup obj_ICIecHdlcSetup(0x00,0x00,0x16,0x00,0x00,0xFF);
//in obj.hpp:
extern ICIecHdlcSetup obj_ICIecHdlcSetup;
now i have a template class:
template <class TValue>
class ICData
{
//some thing
};
but the same way would not work
//in obj.cpp:
ICData <uint8_t> temperture(7,64,41,0,0,255) ;
//in obj.hpp:
extern ICData <uint8_t> temperture ;
and make this error:
Error 10 error LNK2019: unresolved external symbol "public: void __thiscall ICData<unsigned char>::set_value(unsigned char)" (?set_value#?$ICData#E##QAEXE#Z) referenced in function "void __cdecl object_instantiation(void)" (?object_instantiation##YAXXZ) E:\sv_repos\Test\Test\VS2010\Test\Test\Objects.obj Test
thanks in advance.
The error given most likely means the function referenced simply doesn't exist, in general or in the current compilation unit.
Check to make sure it has been defined in the class body (in the header in the templated case) or is being imported properly (if coming from an external source, such as DLL or library; a common issue but unlikely with templates), including the library being linked against.
The form of your extern global variable appears to be correct, and that does work with templates generally speaking. The error seems specific to your templated class, but there is not information on whether that function actually exists in your posted code.

C++: static member functions and variables- redefinition of static variable?

I was trying to incorporate the Singleton design pattern into my code, but I started getting a weird error:
main.obj : error LNK2005: "private: static class gameState * gameState::state" (?state#gameState##0PAV1#A) already defined in gameState.obj
If you're not familiar with the singleton pattern, it is basically used to enforce only 1 instance of a certain object in the entire program.
Here is the relevant code:
gameState.h:
class gameState
{
public:
static gameState* Instance() {return state;}
.
.
.
private:
gameState();
static gameState* state;
};
gameState* gameState::state = new gameState();
and right now I'm just using the instance of that object in the main.cpp file:
gameState *currState = gameState::Instance();
.
.
.
for_each(currState->getHumanPieces().begin(),currState->getHumanPieces().end(), drawPieces);
It would seem I am trying to redefine gameState::state, but can't figure out why... help anyone?
that solved that, but one error still remains, which I didn't actually post before as I thought it was just part of the other one:
error LNK2019: unresolved external symbol "private: __thiscall gameState::gameState(void)" (??0gameState##AAE#XZ) referenced in function "void __cdecl `dynamic initializer for 'private: static class gameState * gameState::state''(void)" (??__E?state#gameState##0PAV1#A##YAXXZ)
any good tip on how to fix that one as well?
Thanks both of you, its fixed :D
You need to put the definition of the static gameState* into exactly one source file, i.e. this line:
gameState* gameState::state = new gameState();
If you put it in a header which is included by multiple source files, each has a definition of gameState::state which leads to errors at link-time.
For the follow-up problem, use Vadakkumpadaths advice: you need to provide a definition for gameStates constructor, not only a declaration.
Add definition for your constructor to fix second linker error.
private:
gameState()
{
}
Use a header guard macro for the redefinition problem, and explicitly define your private constructor.