Unresolved external symbol referenced in function - c++

I realize this is a hard one to answer without providing you with huge amounts of code (which I'll try to spare you).
Essentially i'm getting this error in class X, which #includes the class Y header. The class Y header has three definitions for getters
// Getters
static ID3D10Device* PDevice();
static ID3D10Buffer* PBuffer();
static ID3D10Buffer* IBuffer();
I get three identical errors, all occur in class X. so essentially the error is:
Unresolved external symbol ID3D10Device* PDevice() referenced in function (constructor of class X)
sorry if that's a bit vague. Any idea why this might be happening? I've googled it but I can only really make an educated guess as to what this error is.

First of all this is a linker error.
This linker error means that the mangled name PDevice et al is not found.
Can you make sure that you have an implementation of a function that matches the definition?
Also, maybe obvious but just check that you actualy have an implementation.
If your implementation is in an external lib, be sure you have included the other lib in your linker.
Hope that helps!

Make sure the files that contain the definition and implementation of class Y are added to the project, so that the linker finds the symbols in the Y.o file

Make sure you set the dependencies right (add the lib file). In Visual Studio you can do so by Properties -> Linker -> Input -> Additional Dependencies. In the textbox you can now enter the name of your .lib file.

Another reason this can happen is when both C and C++ source files are used to create a binary. The compiler uses a different naming mechanism for C symbols vs C++ symbols. Please read the "Adding C++ To The Picture" section in this great article. One reason for example is function overloading in C++. The symbol name of the function includes the function signature (argument types and their order). To quote from the article, "all of the information about the function signature is mangled into a textual form, and that becomes the actual name of the symbol as seen by the linker." So, when C code file needs to call a function defined in a C++ file, the C code's object file only mentions the name of that C++ function (doesn't include function signature). The C++ object file however contains the mangled name (which includes the function signature). Hence, the linker reports an "error LNK2019: unresolved external symbol FOO_CPP_FUNC referenced in BAR_C_FUNC". The solution suggested there is to add an extern "C" around the declaration & definition of the C++ function.

Related

MSVC2019 Missing symbol names from static library

I'm newbe with C++ please help me if someone can!
I've made a binary bigint object which work well.
I complied it to a static library and tried to include into an another program but it fails with errors like this:
combinations.obj||error LNK2019: unresolved external symbol "public: static void __cdecl BinBigInt::bifactorial(class BinBigInt const &,class BinBigInt &)" (?bifactorial#BinBigInt##SAXAEBV1#AEAV1##Z) referenced in function "unsigned __int64 __cdecl combi::nonrepCombination(char,char,class std::basic_string,class std::allocator >)" (??$nonrepCombination#D#combi##YA_KDDV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z)|
If i copy paste the two code together everything is work well so the codes seems to be OK.
I read a lot of topics about the LNK2019 error and checked the compiler settings and Release vs. Debug version matching and so on but nothing helped.
At last I checked the symbols in the .lib file manually with MS dumpbin as guessed in some topic to check name manling problems but I found that a lot of (9) function name and all (7) of internally defined operators really not contained by the .lib file. (compiler just pop up 5 unresolved external symbol error those thats which I really tryed to used in the implementing file.)
It seems to be not just a name manling problem I absolutely not found those symbol names with dumpbin.
While lot of other functions which defined inside the object and operators (like Comparisson, bitwise etc.) which defined out of the object is contained by the .lib file.
I used: dumpbin /symbols binbigint.lib | findstr "function name" in a lot of version to check them.
I use Code::Blocks with MSVC2019 host and target both x64.
Someone have any guess what can couse that the lib didn't contain some symbols?
(The library code is about 3.000 row long so I didn't copy here...)
Well. I found the problem...
That was me... :(
Originally I've wrote the whole object declaration and definition inside the object scope in a .cpp file.
And it worked well. And I thought will be enough to delete the implementetion parts in the header and I can leaving the whole class code with the class header in the .cpp too and I forget include the .h to the .cpp so compiler not generated errors about it.
The fact that it works with Copy paste put me on the right track (that must be some problem with the .h+.cpp version) at the end.
Sorry for disturbing!
(This was my first class which I try to use as .lib)

How could a function call cause an unresolved external in some places, but not others?

I've read many of the answers on SO regarding unresolved externals, but only one seemed close to my situation (Unresolved external symbol for some function calls but not all), but the answers don't help.
Here's my situation: I'm using VS 2015 and compiling a .dll that uses several static libraries. (All the libraries are part of my VS 'project' - meaning I'm in control of all the code - I'm not using libraries from other sources yet).
By the way, I'm using the term "library" pretty loosely here. These are all C++ 'projects' in my VS 'solution' that create static libs, but they're mostly meant for code organization. They're not meant to be used in other projects or by other coding groups.
I have a global function that can be called in the library code. The declaration is in a header file that I #include where I want to use the function (the header file uses both #pragma once, and #ifndef guards). The definition is in the .dll code.
Here's what I don't understand: If I use the global function in some of the classes defined in my libraries, I'll get an unresolved external error. But, I can comment out the line, and the the .dll will compile, link, with other places in the code, from the same "library", successfully using the global function, called in the same manner. I run the code with a simple console app and the places that use the global function do indeed get appropriate returns from it. So, the global function does get resolved correctly.
From what I've read about 'unresolved external' errors, it seemed to me that either the linker should be able to resolve a reference, or not. If not, then shouldn't any of the calls to the global function result in an unresolved external, and keep the code from linking?
I feel like I'm missing something fundamental here. I'm not quite sure how go about trying to solve this. Instinct says to compare the code where it works (global function call doesn't cause linker errors) with where it doesn't. But, I can't see a difference from a linking perspective. All of the files that use the global function have to include the header with the function declaration, which they do (or the compiler would complain).
Any ideas, suggestions or insights are welcome. If you made it this far, well, thanks for your time!
Just in case the actual error might be helpful, here it is:
WindogEngineLibd.lib(ColumnFinder.obj) :
error LNK2019: unresolved external symbol "class IUserPreferences & __cdecl global_user_prefs::GetUserPreferences(void)" (?GetUserPreferences#global_user_prefs##YAAEAVIUserPreferences##XZ) referenced in function "public: class std::vector<struct std::pair<class std::weak_ptr<class CDataColumn const >,class std::weak_ptr<class CDataColumn const > >,class std::allocator<struct std::pair<class std::weak_ptr<class CDataColumn const >,class std::weak_ptr<class CDataColumn const > > > > __cdecl CColumnFinder::EvaluateDualExpressions(class CColumnExpression,class CColumnExpression)const " (?EvaluateDualExpressions#CColumnFinder##QEBA?AV?$vector#U?$pair#V?$weak_ptr#$$CBVCDataColumn###std##V12##std##V?$allocator#U?$pair#V?$weak_ptr#$$CBVCDataColumn###std##V12##std###2##std##VCColumnExpression##0#Z)
Edit 1
I'm going to add some pseudo code to (hopefully) make my situation more clear.
FileA.h in static lib 1 (the header file I include where needed)
float GlobalFunction();
FileB.cpp in static lib 2 (.cpp file for one class that uses GlobalFunction)
#include FileA.h;
float ClassWidget::UseGlobalValue()
{
return GlobalFunction() * 2.0f; // no problem with this line
}
FileC.cpp in static lib 2 (.cpp file for another class that tries to use GlobalFunction, in the same library as ClassWidget)
#include FileA.h;
float ClassThingy::TryToUseGlobalValue()
{
return GlobalFunction() * -1.0f; // uncommenting this line will cause link error
}
In the .dll project, I include the same header file:
FileDll.h
#include FileA.h;
And then define the function:
FileDll.cpp
float GlobalFunction()
{
return 2.0f;
}
If I comment out the definition of 'GlobalFunction' in FileDll.cpp, then all of the calls to 'GlobalFunction' cause unresolved external errors when I compile the .dll. With it there, all of the errors are resolved (including the one in ClassThingy).
When I try to use my .dll in a console app, the call to GlobalFunction in ClassThingy causes a link error, while the call in ClassWidget does not.
I'm pretty certain this has to do with way the .dll is getting linked, but I can't figure out how. If I create a console app that uses the static libs directly, and have it define 'GlobalFunction' - everything is fine, no link errors. If the console app were my goal, I'd just do that. But, the .dll is my goal - the console apps are just for testing.
I looked into using the 'extern' keyword, but from what I can tell, that's superfluous for file scoped functions.
Thanks again for any help, insight.

redefinition happend in which procedure? compile or link time?

If I defined a function twice, I'll get a redefinition error message, but
I'm confused that redefinition happened in compile or link time?
and why you can override malloc in libc without a redefinition error?
You get a function redefinition error when you have two function with the same prototype or signature (function signature is made of the function name number of parameters and parameter types, does NOT include the return type).
This is a compile time error if the compiler see two functions with the same signature:
int foo(int a);
double foo(int b);
Why you can override function calls in libraries? Let's look at how the code is build into an executable:
the compiler is called for each source file and outputs an object file: any function call which cannot be resolved (i.e. calling a function in a different file) is an external symbol which the linker will have to resolve.
the linker take all the object files and tries to resolve all the symbols; but it does this on a first come first served manner. For a external symbol it will consider the first definition it finds and not worry about the fact that there may be more definitions of the same symbol available.
So, the linker actually allows you to override a function's behavior. And it all depends on the order the files are linked - the first function definition it finds is the one used to resolve the symbol.
Hope this sheds some light on the matter.
Either or both. It can also result from the programmer editing source code or modifying build scripts.
"Redefinition" errors are emitted when the linker find two things (symbols) with the same name.
There are many reasons the linker might find two symbols with the same name. Some possibilities (there are many permutations) include;
An object file is specified twice in the link command. This usually results from an error in a build script.
Two object files that contain the same function definition. This results from code duplication - for example, a function definition being copied into different source files, which are then compiled and linked. It can also result from monkey business with the preprocessor (e.g. #includeing a file that contains the definition of a global variable by two source files).
The causes of things like the above are generally programmer error (e.g. supplying a bad linker command in a build script, misuse of the preprocessor, copying and pasting code between projects.
The reason functions in libraries like libc can often be "overridden" is that the linker typically only looks for symbols in libraries if it can't find them in object files. So, if an object file defines malloc() the linker will resolve all calls to that, and not attempt to resolve using the version in a library. This sort of thing is quite dangerous, because some other functions within libraries (e.g. even within libc) may resolve directly to the original malloc() (e.g. some calls may be inlined) which can unpredictable behaviours. This sort of behaviour is also linker specific: although this sort of thing is common with unix/linux variants, there are systems where the linkers do things differently.

Can not find bsearch(vc2008) even include the header file

I maintain an old project and encountered some linker errors.
The error message is:
error LNK2019: unresolved external symbol __imp__bsearch referenced in function "bool __cdecl is_sync_host
As far as I know, the bsearch function is included in the header file "cstdlib" or "stdlib.h", but even if I include the header, I can't find "bsearch".
I suspect this is due to the fact that this old project ignores some lib because of symbol conflicts (I also don't know why they prefer to omit the lib instead of renaming the functions)
The ignored libs : msvcrt.lib;msvcrtd.lib;libcmt.lib;libc.lib
I try to add those ignored libs back, but then I encounter a lot of "symbol redefinition" problems and I don't think that renaming those functions is an applicable solution.
I found a work around (replace the bsearch to std::binary_search), but I want to know why and how to solve this problem properly (how comes the compiler can't find the bsearch?). Thanks.
error LNK2019:
This is a linker error. Your code compiled just fine (.c > .o), it is the linking that gives you problems (.o > .exe).
The ignored libs : "msvcrt.lib;msvcrtd.lib;libcmt.lib;libc.lib"
This means the code is ignoring the C standard library, so no wonder it doesn't find the standard bsearch() function...
The question is, why? There is simply no reason (that I could think of) for well-written code to explicitly ignore the standard library.
I try to add those ignored libs back, but then I meet a lot of "symbol redefinition" problems...
Which brings me to the conclusion that your code is not "well-written", at which point it is very difficult to give advice without seeing the code, or telling you to "ditch it, it's crap". ;-)
I don't think that rename those functions is an applicable solution.
If you have functions in your project that are named like standard library functions, unless your project is a standard library, they are misnamed and should be renamed.
But at this point, I would really like to see the code in question to figure out what the original programmer might have had in mind...

C++ - Import of explicitly specialised templates on Windows

I am having some trouble getting a program to link on Windows with VC2008 SP1.
I am explicitly specialising a template member function in a DLL, which appears correctly as an exported symbol in dependency walker, for the correct type, and with the correct arguments.
When I try to call the symbol from an .exe, the linker complains that it can't resolve the symbol (although it compiles the object ok), however the decorated name of the symbol it says that it can't resolve exactly matches the decorated name of the exported symbol in my DLL (as viewed with dependency walker) The problem only occurs for explicitly specialised exported template member functions. If I comment the calls to these, all other exported functions classes will link ok, so the .lib looks like it is being generated ok.
I have tried changing my declaration of the template function in the headers to include the 'extern' directive, and it has the customary __declspec(dllimport) correctly specified, but this makes no difference.
Any ideas appreciated. Thanks.
Finally managed to get to the bottom of this - it was caused by a .lib that didn't get checked-in to match the DLL from source control - maybe built with a different compiler version.
Sorry for any wasted time.
... if all else fails, try rebuilding your library dependencies.