Unresolved external symbol error (LNK2019), after inlcuding headers

Dennis Schwartz picture Dennis Schwartz · Apr 2, 2012 · Viewed 15.9k times · Source

I know this has been asked probably a thousand times, but I've been biting my nails on this one for a few days now. I'm fairly new to C++ and this is my first time using Visual Studio.

I'm trying to modify the TORCS Racing Simulator for a competition at my University. Most of this has already been done, so only parts of what I'm posting is actually my code. But I added some new functions to it and I'm having trouble with them.

The whole thing worked fine in Linux with g++ but when I try to compile it in Visual Studio 2005, I get an Unresolved external symbol error.

I added a new project to the Solution, which uses functions from other projects.

In this new project I call the function:

getisDerbyDuel()

which is declared in raceinit.h, which I included in the new project.

#ifndef _RACEINIT_H_
#define _RACEINIT_H_

#define RACE_ENG_CFG    "config/raceengine.xml"

extern void ReInit(void);
extern void ReShutdown(void);
extern void ReStartNewRace(void * /* dummy */);
extern void ReAddRacemanListButton(void *menuHandle);
extern int  ReInitCars(void);
extern int  ReInitTrack(void);
extern void ReRaceCleanup(void);
extern void ReRaceCleanDrivers(void);
extern char *ReGetCurrentRaceName(void);
extern char *ReGetPrevRaceName(void);
extern bool getisDerbyDuel(void);
extern void setisDerbyDuel(bool isDerbyDuel);

extern tModList *ReRaceModList;

#endif /* _RACEINIT_H_ */

and defined in raceinit.cpp:

 bool _isDerbyDuel = true;

void setisDerbyDuel(bool isDerbyDuel) {
    _isDerbyDuel = isDerbyDuel;
}
bool getisDerbyDuel(void) {
    return _isDerbyDuel;
}

The raceinit.h and raceinit.cpp are in a different projects in my Solution called client, which compiles without errors. I also added the client.lib to the dependencies in my project.

When compiling I get the following output:

1>Generating Code... 
1>Compiling resources...
1>Linking...
1>   Creating library .\Release/championship2010server.lib and object      .\Release/championship2010server.exp
1>championship2010server.obj : error LNK2019: unresolved external symbol "bool __cdecl     getisDerbyDuel(void)" (?getisDerbyDuel@@YA_NXZ) referenced in function "void     __cdecl drive(int,struct CarElt *,struct Situation *)"     (?drive@@YAXHPAUCarElt@@PAUSituation@@@Z)
1>.\Release/championship2010server.dll : fatal error LNK1120: 1 unresolved externals
1>Build log was saved at "file://c:\Users\Administrator\Desktop\torcs-verylasttry    \src\drivers\championship2012server\Release\BuildLog.htm"
1>championship2010server - 2 error(s), 9 warning(s)
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========    

Any ideas are appreciated, I don't know what to try anymore.


EDIT:

Thanks for your answers. I tried changing the external thing, so the flag itself is declared external in the header file and the getter is not (and several combinations) but nothing seems to change the error output.

I'm not exactly sure what is meant by exporting the functions. A quick Google search lead me to this:

[..]
extern void ReRaceCleanDrivers(void);
extern char *ReGetCurrentRaceName(void);
extern char *ReGetPrevRaceName(void);
#ifdef __cplusplus
extern "C" {  // only need to export C interface if
              // used by C++ source code
#endif
extern bool __declspec( dllimport ) getisDerbyDuel(void);
extern void __declspec( dllimport ) setisDerbyDuel(bool isDerbyDuel);

#ifdef __cplusplus
}
#endif
extern bool _isDerbyDuel;
[...]

and

extern "C" {
#include <raceinit.h>
}

Which changed the error Output to this:

1>championship2010server.obj : error LNK2019: unresolved external symbol     __imp__getisDerbyDuel referenced in function "void __cdecl drive(int,struct CarElt *,struct     Situation *)" (?drive@@YAXHPAUCarElt@@PAUSituation@@@Z)
1>.\Release/championship2010server.dll : fatal error LNK1120: 1 unresolved externals

I just don't know whats wrong here.


EDIT TWO:

So, after reading up on importing/exporting functions I adjusted my code.
The header file, where the unresolved function is declared now looks like this:

#ifdef __cplusplus
extern "C" {  // only need to export C interface if
              // used by C++ source code
#endif
 __declspec( dllexport ) bool getisDerbyDuel(void);
 __declspec( dllexport ) void setisDerbyDuel(bool isDerbyDuel);

#ifdef __cplusplus
}
#endif
extern bool _isDerbyDuel;

The file where I call the function doesn't have a header file, but I tried to declare the imported function according to the other functions in the file:

[...]
static tTrack *curTrack;
static int RESTARTING[NBBOTS];

static void initTrack(int index, tTrack* track, void *carHandle,
        void **carParmHandle, tSituation *s);
static void newrace(int index, tCarElt* car, tSituation *s);
extern "C" void drive(int index, tCarElt* car, tSituation *s);
static void endrace(int index, tCarElt *car, tSituation *s);
static void shutdown(int index);
static int InitFuncPt(int index, void *pt);

__declspec( dllimport ) bool getisDerbyDuel(void);
[...]

The header is included just like any other and the function is called like this:

if (getisDerbyDuel()) {
[...]

The error output now changed to this:

error LNK2019: unresolved external symbol _getisDerbyDuel referenced in function _drive

So it seems to me that if I just solved some C/C++ compatibility issue (or made it worse, I'm not even sure anymore) but the linker problem remains unchanged.

Any Ideas? I'm kinda put off now, but I need to get this to work, or my Boss is going to be pissed :)

Answer

Dennis Schwartz picture Dennis Schwartz · Apr 4, 2012

As i said, I'm new to Visual Studio but this is still a little embarassing. I found my error and it actually wasn't in my code.
In addition to the linker input etc. i had to add the project containing raceinit.cpp to the references in my new project. That solved my problem.