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.