Qt5 unresolved external to staticMetaObject function - c++

I have a class that is derived from QObject and QRunnable and also has the Q_OBJECT macro. The library that contains the class compiles fine and I get a .lib and .dll file. I'm using MSVC 2013 and QT 5.4 (precompiled binaries from qt.io).
Looking at the DLL using Dependency Walker, I can see that the function is there. The file get's moc'ed which means I can look at the resulting CPP file. As a proof here's the function that's causing the trouble.
const QMetaObject DHImageConvHandler::staticMetaObject = {
{ &QObject::staticMetaObject, qt_meta_stringdata_DHImageConvHandler.data,
qt_meta_data_DHImageConvHandler, qt_static_metacall, Q_NULLPTR, Q_NULLPTR}
};
Now, when I try to create an app that links to this library I get the following error.
unresolved external symbol "public: static struct QMetaObject const DHImageConvHandler::staticMetaObject" (?staticMetaObject#DHImageConvHandler##2UQMetaObject##B)
referenced in function "public: static class QString __cdecl DHImageConvHandler::tr(char const *,char const *,int)" (?tr#DHImageConvHandler##SA?AVQString##PBD0H#Z)
Changing the project type for the library from "Dynamic Library" to "Static Library" makes this go away but I'm curious why. The code is in the lib. I opened the import library with a text editor and looked for staticMetaObject and, as mentioned previously, Dependency Walker also shows that it's there.
Can anyone shed some light on this?
edit 10.01.2015
I misspoke about who is using the library in question. That lib is linked to another lib which is then part of an app.

Thanks Archie for pointing me into the right direction. The dllimport/dllexport prefixes are part of the code - wait for it - but every library is using the same macro and preprocessor directive. That means, when my problem library is used by code of another library, and both use the same macro to export their symbols, the second library includes the headers of the first library with dllexport instead of dllimport. As soon as I gave my problem lib its own dllexport/dllimport macro everything worked.

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)

Unresolved Symbol Errors for C++/CLI dll in C++ Project

I am trying a very simple implementation of a C++/CLI wrapper to allow legacy C++ code to reference .Net code, as described here. I am getting stuck just trying to get my basic C++/CLI unmanaged (native) objects linked, without even including any managed/IL/.Net code.
My question is, following along with this basic setup and what I describe below, am I right to be very confused about these errors? Are there some considerations that I'm missing? Maybe the answer is that this should work, so it's not clear what's wrong. That's still helpful. A similar working example would be great.
Unresolved Symbol Errors
Error LNK2019 unresolved external symbol "__declspec(dllimport)
public: __thiscall Wrapper::Test::Test(void)"
(__imp_??0Test#Wrapper##QAE#XZ) referenced in function _main NativeApp
Error LNK2019 unresolved external symbol "__declspec(dllimport)
public: __thiscall Wrapper::Test::~Test(void)"
(__imp_??1Test#Wrapper##QAE#XZ) referenced in function _main NativeApp
I've reviewed related questions on SO without any luck. I've got my dll header included in the client C++ project, my project reference to the C++/CLI wrapper dll, and my define statements for import/export. My very simple code is shown below. I am not using any MFC. I am using VS2017. DumpBin.exe /exports shows export symbols that seem to match what the linker error says are missing.
1 0 000010D0 ??0Test#Wrapper##QAE#XZ = ??0Test#Wrapper##QAE#XZ (public: __thiscall Wrapper::Test::Test(void))
2 1 000010E0 ??1Test#Wrapper##QAE#XZ = ??1Test#Wrapper##QAE#XZ (public: __thiscall Wrapper::Test::~Test(void))
3 2 000010C0 ??4Test#Wrapper##QAEAAV01#ABV01##Z = ??4Test#Wrapper##QAEAAV01#ABV01##Z (public: class Wrapper::Test & __thiscall Wrapper::Test::operator=(class Wrapper::Test const &))
Here's the basic code...
NativeApp.exe (project)
NativeApp.cpp (File)
#include "stdafx.h"
#include <iostream>
#include "Wrapper.h" //From additional includes directory
int main()
{
std::cout << "Program Started" << std::endl;
Wrapper::Test shell = Wrapper::Test::Test(); //Use dll
std::cin.get();
return 0;
}
Reference to Wrapper
Wrapper.dll (Project)
Wrapper.cpp (File)
#include "Wrapper.h"
#pragma unmanaged
namespace Wrapper {
Test::Test() {
}
Test::~Test() {
}
}
Wrapper.h (File)
#pragma once
#ifdef WRAPPER_EXPORTS
#define WRAPPER_API __declspec(dllexport)
#else
#define WRAPPER_API __declspec(dllimport)
#endif
#pragma unmanaged
namespace Wrapper {
class WRAPPER_API Test {
public:
Test();
~Test();
};
}
I was under the impression that the project reference took care of any additional dependency settings behind the scenes. Apparently, that is not the case. The .lib file needed to be added as an additional dependency, as is described here. However, as described by this Microsoft document, everything worked without additional dependencies when I was using non /clr dlls, so I'm not sure why the additional dependency was only required for my CLR reference. Clearly, I need to read up on this some more.
In any case, my C++ client project requirements are listed below. I was missing the second requirement. Also, here is an example project that helped me diagnose the problem.
1.) Add project reference
2.) Add the .lib file as an `Additional Dependency.
[Optional] Use Additional Library Directories
3.) #include .h file in code where appropriate
[Optional] Use additional include directories
EDIT: Why the additional dependency was required, and alternative option
As noted above, I was getting hung up on why the .lib additional dependency was required for the /clr dll but not for the non-clr dll. The answer is because a /clr project is configured by default to ignore import libraries. So when the project gets referenced by another C++ project, the project reference ignores import libraries. Changing this setting (Linker > General > Ignore Import Libraries) to "No" in the /clr dll project solves the issue so that the additional dependency is not required and the project reference works the same as the non-clr C++ dll.

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.

LNK2019 when converting an app to use DLLs

(Re-written for clarity)
I have a multi-project solution that I am looking to convert from using .lib to .DLL files. I have created my __declspec macros and applied it to every class except for those in the project that creates the final .exe. The linker is throwing a fit on just about everything, however. I have set up to ignore errors about exporting templated objects.
One example is this:
error LNK2019: unresolved external
symbol "__declspec(dllimport) public:
void __thiscall
Rail::SetNextRail(class Rail *)"
(__imp_?SetNextRail#Rail##QAEXPAV1##Z)
referenced in function "public: static
void __cdecl
MyUtilities::CreateBezierRails(int,class
MyVector *,class std::vector > &)" (?CreateBezierRails#MyUtilities##SAXHPAVMyVector##AAV?$vector#PAVRail##V?$allocator#PAVRail###std###std###Z) MyUtilities.obj
Unresolved external symbol on my __declspec(dllimport)? That doesn't seem right. It is getting placed by a macro such as:
#ifdef MYAI_EXPORT
#define DECLSPECAI __declspec(dllexport)
#else
#define DECLSPECAI __declspec(dllimport)
#endif
Basically, what gives? Why am I getting these errors and how can I fix them? Thank you to everybody who has tried to help thus far, but I am still stuck with this.
Are you linking against MyRenderer.lib?
Do you export your functions and classes using
__declspec(dllexport)
and import them using
__declspec(dllimport)
? If not, you will have to do this. In your header, during compiling the DLL, you will need to have the dllexport clause, and when using the header in other DLLs or EXEs, you will have to use the dllimport clause. You can easily do this by defining a macro like
// set this in preprocessor options for the DLL
#ifdef MYDLL
# define MYDLL_IMPORTEXPORT __declspec(dllexport)
#else
# define MYDLL_IMPORTEXPORT __declspec(dllimport)
#endif
class MYDLL_IMPORTEXPORT MyClass {};
Well its saying that it found a declaration but no implementation. Are you sure you are compilnig the file with the function implementation in it? Have you remembered to put the MyRenderer:: before the DrawVertices call? Are you sure you are linking both the libraries into the executable?
Edit: When compiling a lib the library leaves a stub, effectively, saying I want this function when you can link it to me.
When you run the linker it runs through all the libraries looking for these stubs and "links" them to the actual implementation. Each cpp file you build compiles to an object file and this object file works in exactly the same way. If it can't link the stub to the actual function then you get a linker error such as you are seeing. Thus, either your renderer library is not being linked into the executable OR the implementation is missing something vital such as the MyRenderer::. Though if it was the latter i'd expect other problems to arise such as the lack of a IDirect3DDevice which, i assume, is a member of the class. Thus, most probably, you are failing to link the .lib in.
there are different configurations of DLLs.
staticly linked DLL - the implementations are in a DLL, and the definitions are in a .lib. You statically link to the .lib (which is kinda like a header), and the lib tells c++ how to call the function. this is probably what you want. make sure you get your __declspecs right.
dynamically linked DLL - everything is in the DLL, the definitions are also in the DLL, you need to manually set up function pointers to all the exported things, which are indexed by a string at runtime.
Google will help and made this CW so someone can make this answer suck less.
i also advise you to get DLLs working in a skeleton app.

How can I resolve "error LNK2019: unresolved external symbol"? [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 8 years ago.
I've got this MFC application I'm working on that needs to have an embedded database. So I went hunting for a slick, fast "embeddable" database for it and stumbled accross SQLite.
I created a DB with it, and I created a static library project with Visual Studio 2008. the library project will be used in another main project.
In the library project, I created a class DBClass with a method AddFeedToDB(CFeed f). The library project uses the .lib file from codeproject (cppsqlite3.lib).
When compiling the static library, no error is detected, but when I try to use the library project file in the main project, I get these type of errors:
error LNK2019: unresolved external symbol "public:void __thiscall
CppSQLite3DB::close(void)" (?close#CppSQLite3DB##QAEXXZ
referenced in function "public: int __thiscall
CTalkingFeedsDB::AddFeedToDB(class CFeed,char const*)" (?
AddFeedToDB#CTalkingFeedsDB##QAEHVCFeed##PDB#Z
What am I missing?
I know it is already 2 years since this question... but i run in the same situation here. Added all the header files... added the lib directories.. and keep having this error.
So i added manually the lib to the Configuration Properties -> Linker -> Input -> Aditional Dependencies
and all works for me.
It happened to me more than once that I thought symbol XXX (i.e. ?close#CppSQLite3DB##QAEXXZ) was in the import lib, while the actual symbol was __impXXX (i.e. __imp?close#CppSQLite3DB##QAEXXZ).
The reason for the linker error is then to be found in the compilation step: the compiler will generate the ?close#CppSQLite3DB##QAEXXZ symbol to be imported, where it should generate __imp?close#CppSQLite3DB##QAEXXZ. This often means that the function declaration itself didn't have __declspec( dllimport ). Which may be caused by some preprocessor symbol not being defined. Or the __declspec not being there at all...
Don't know if it is your case, but the imp prefix may mean that you are compiling a x64 library in a Win32 project.
You either need to link the codeproject SQLite lib to your executable, or to include the sources files in your project directly. (Which one did you do ?)
I would follow these steps:
think about what library or .obj file you expect the symbol to be exported by.
check whether it actually does export that very symbol (check character-wise). Sometimes, it's the calling convention differs.
check if the library you expect to contain the symbol is known to the linker - first check for the 'additional libraries', then check if the library is actually found (I mostly do this by using filemon.exe from sysinternals, and look for link.exe to open the lib file. )
After thinking a while, you may find that your library project will not export the sought for function. That function is in the database lib. You should add that lib to your main project. It's no use adding it to your static lib project.
The compiler and linker will not link one library into another (unless one is a DLL). You need to specify both libraries (cppsqlite3.lib and your own static library) in your main project.