Unresolved external symbol (including a library) c++

Started by
12 comments, last by EarthBanana 5 years, 6 months ago

Hi!

Im using visual studio 2017 and has run into a problem I didnt have before. 

I include the libnoise library (for perlin noise) and I now get:


1>world.obj : error LNK2019: unresolved external symbol "public: virtual __thiscall noise::module::Module::~Module(void)" (??1Module@module@noise@@UAE@XZ) referenced in function "public: virtual __thiscall noise::module::Perlin::~Perlin(void)" (??1Perlin@module@noise@@UAE@XZ)
1>world.obj : error LNK2019: unresolved external symbol "public: __thiscall noise::module::Perlin::Perlin(void)" (??0Perlin@module@noise@@QAE@XZ) referenced in function "void __cdecl noiseFillArray(int,int,float *,int,int,int,float,float)" (?noiseFillArray@@YAXHHPAMHHHMM@Z)
1>world.obj : error LNK2019: unresolved external symbol "public: virtual double __thiscall noise::module::Perlin::GetValue(double,double,double)const " (?GetValue@Perlin@module@noise@@UBENNNN@Z) referenced in function "void __cdecl noiseFillArray(int,int,float *,int,int,int,float,float)" (?noiseFillArray@@YAXHHPAMHHHMM@Z)

I have included the headers in the "include directories" and the binaries (dll and lib) in the "library directories" for the project as stated in the library tutorial.

Is it connected to the "runtime library" setting? I needed to change this from "multi-threaded" to "multi-threaded DLL" when my game engine upgraded. Should I include the library in a different way now?

I appriciate the help!
Erik

Advertisement

How are you including the .lib file?  #pragma or through visual studio settings pointing to the correct directory?

"Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety." --Benjamin Franklin

No pragma, only through the settings for the project.

Anyone? I really dont know how to proceed...

On 10/3/2018 at 8:54 AM, suliman said:

I have included the headers in the "include directories" and the binaries (dll and lib) in the "library directories" for the project as stated in the library tutorial.

Did you add the actually library file (aka libnoise.lib) to Additional Dependencies under Linker->Input?

Yes I do. (But i realize that if I misspell it I get no extra error, does this tell me something?)

If i remove #include <noise.h> i can compile (but then of course I cannot use the functions i need from the library)

Did you verify that the missing functions are defined in the header file? (they should be)

Perhaps this noise thing library is messed up. Did you try another library? (using the same path as much as possible) Since linking is all you want to try, perhaps write a trivial test program to try it? Easier to change than your main game program, and if you make a mess of it, you can just delete everything without doing any harm.

 

It DID work fine. Then I hade to upgrade my visual studio version and change my "runtime library" setting from "multi-threaded" to "multi-threaded DLL".

And now it doesnt work :(

I include noiseEpa.h in my game. And that file can be reduced to (see below). If i comment out the Perlin m line it's fine but with it I get unresolved externals. The perlin module is from the noise-lib and what I need in my project.

 


#include <noise/noise.h>
using namespace noise;

void noiseFillArray()
{
	static module::Perlin m;
}

Have you rebuilt the library with the new runtime library settings? (And do the other build settings match?)

38 minutes ago, suliman said:

I include noiseEpa.h in my game. And that file can be reduced to (see below). If i comment out the Perlin m line it's fine

Include files have no relation to library files. The only thing in common between them is that the developer should describe the content of the latter in the former, that's all.

What you see as "the compiler" is really at least 2 programs (and probably more, but 2 is enough for the explanation). One program is the "true compiler", and the other one is the linker. The "true compiler" reads your C++ files, and your include files, and checks if they make sense (stuff that you use must be declared somewhere in the same or another file). If it is happy, it produces one or more object files. This is the compiled C++ code.

In particular, this compilation step takes the content of include files (and your c++ files) as the one and only truth, it does not check for existence of library files, nor does it do any other form of checking on your library files at all.

Once all object files have been produced, everything is shipped to the linker. The object files are all partial files, they have "holes" where the linker can insert calls to other object files, and to libraries. Each hole has a name associated with it, so the linker knows what it should insert at that point.

The linker doesn't care about your source code at all, it just has these object files and libraries, which all have some names of routines that they have code for, and holes with a name for calls to other objects files (and libraries). The linker places all object file after each other, and resolves each hole by finding a matching name in some other objec file. If it runs out of holes to resolve, it's happy, and you have an executable program.

If it can't resolve a hole due to missing a routine with a matching name, it throws errors printing the name (in a pretty c++ notation) of routines that it misses.

 

If you remove the Perlin line, you basically have the true compiler generate a few less holes in one of the object files. The linker becomes happy as well then, as it can resolve all other holes (there were no other missing routines in its report previously), and "it works". It's not because you fixed anything, you just eliminated the need for having the library around for the linker.

This topic is closed to new replies.

Advertisement