MSVC Unresolved Eternal Symbols in DLL - c++

Can someone help me understand why MSVC 12 2013 reports these symbols are unresolved?
Error 239 error LNK2019: unresolved external symbol "public: static double const Wm3::Math<double>::DEG_TO_RAD" (?DEG_TO_RAD#?$Math#N#Wm3##2NB) referenced in function "protected: void __cdecl Matt::ExternalNavConverter::CExternalNavConverter::DoProcessExternalNav(void)" (? DoProcessExternalNav#CExternalNavConverter#ExternalNavConverter#Matt##IEAAXXZ) C:\Users\mrussell\workspace\Matt\build-conan-Release\Libraries\MattClient\ExternalNavConverter.lib(ExternalNavConverter.obj) MattClient
The symbol DEG_TO_RAD is defined in my Wml.dll file, which I'm quite sure is in my %PATH% when I start MSVC.
The output from dumpbin for the DLL is:
dumpbin /exports C:\Users\mrussell\.conan\data\wml\3.x\ntc\stable\package\a4501f33ae09df332b76b4d6f0e5cebffbe83874\bin\Wml3.dll | grep -i DEG_TO_RAD
143 8E 00031A64 ?DEG_TO_RAD#?$Math#M#Wm3##2MB
144 8F 00031A98 ?DEG_TO_RAD#?$Math#N#Wm3##2NB
And for the LIB:
dumpbin /exports C:\Users\mrussell\.conan\data\wml\3.x\ntc\stable\package\a4501f33ae09df332b76b4d6f0e5cebffbe83874\lib\Wml3.lib | grep DEG_TO_RAD
?DEG_TO_RAD#?$Math#M#Wm3##2MB (public: static float const Wm3::Math<float>::DEG_TO_RAD)
?DEG_TO_RAD#?$Math#N#Wm3##2NB (public: static double const Wm3::Math<double>::DEG_TO_RAD)
I set up a minimal example showing the failed linking here, unfortunately I'm not sure I can put the headers or .lib file.
I'm not that familiar with dumpbin, I'm more accustomed to nm with c++filt.. But to me, this suggests that the symbol DEG_TO_RAD is exported in the DLL.
In the Linker command line window, I can see that by bin path (path the to DLL) is provided as a /LIBPATH, and the full path to the .lib is provided as well (provided in "Additional Dependencies".)
Could this be because I might be mixing up shared and static libs together? Or a sign that despite me thinking the DLL is in my path, somehow it isn't? Or the symbols in the DLL aren't actually there? (the equivalent of a non-T for the symbol type in nm)
I'm going through the list given in this answer, but so far am just confused as to why it is not working.

The issue was that while the WML symbols were exported properly with __declspec(dllexport), they weren't being imported properly by my app.
In the minimal working example I added a snippit of Wm3Platforms.h where dllexport and dllimport are declared. Typically (in my experience) at least, these are controlled by a single preprocessor definition (if on, do dll_export, if off, do dll_import), but this code demands WM3_DLL_IMPORT is declared to make it importable.
Declaring WM3_DLL_IMPORT fixed my issue.
So, turns out my issue was specific to this lib's source code....

Related

Link errors with GraphicsMagick

I downloaded and compiled GraphicsMagick, 1.3.23, Q16, x64, StaticMT version. I had to convert the Visual Studio 7 solution generated by GraphicsMagick's build utility to Visual Studio 2015 format. I linked my project to CORE_DB_magick_.lib and CORE_DB_Magick++_.lib.
When the linker ran, it produced unresolved external symbols when linking InitializeMagick() and DestroyMagick()
1>wtd.lib(WebController.obj) : error LNK2019: unresolved external symbol __imp_DestroyMagick referenced in function "public: __cdecl Wt::WebController::~WebController(void)" (??1WebController#Wt##QEAA#XZ)
1>wtd.lib(WebController.obj) : error LNK2019: unresolved external symbol __imp_InitializeMagick referenced in function "public: __cdecl Wt::WebController::WebController(class Wt::WServer &,class std::basic_string,class std::allocator > const &,bool)" (??0WebController#Wt##QEAA#AEAVWServer#1#AEBV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##_N#Z)
I can't understand why the symbols are not being linked. Any ideas?
Apparently, GraphicsMagick Static versions do not link properly.
What is your project type? I had a similar problem when trying to link the GraphicsMagick libraries to a DLL.
The clue here is that __imp is the function decoration for DLL imports, so you're trying to link with DLL functions.
The problem is that the header magick/common.h, when linked to a DLL project, reads the current configuration of the Visual Studio pre-processor environment to determine which mode the library is in, which is obviously wrong if you're trying to link static libraries into your DLL, for example. In this case, it defines MagickExport to __declspec(dllimport).
AFAIK this is a bug in the library. For proper static build support, magick/common.h needs to do something like read information from the magick/magick_config.h to determine what mode the library was actually built in and define MagickExport appropriately.
Since your library is statically linked, you can fix this by commenting out everything in the define:
#if defined(MSWINDOWS) && !defined(__CYGWIN__)
and replacing it with:
#define MagickExport
#define ModuleExport
#define MagickGlobal

LNK2019 error One DLL linking wih MFC DLL

I'm new to MFC.
I'm trying to make a DLL in MFC, which links to another DLL.
The problem is when I try and compile, I get a LNK2019 error thrown at me for a function present in the DLL which I'm trying to link.
LNK2019 is when the DLL or the function inside the DLL is not being found.
I've taken all steps, the DLL is placed in a known location, the lib is placed in a known location too, it's been added in the additional dependencies, all correct switches have been applied ( ones I know of anyway ).
I've used Dependency walker and I know the DLL, to which I'm trying to link, exposes this function.
I've other examples of use of the function, and I'm trying to use it exactly like it.
The .lib and .dll are in agreement, i.e., they're consistent with each other.
But still the error persists.
EDIT
This is the error message :
Error 2 error LNK2019: unresolved external symbol
"__declspec(dllimport) public: bool __thiscall
PwServer::Connect(wchar_t const *,unsigned long,unsigned long *)"
(_imp?Connect#PwServer##QAE_NPB_WKPAK#Z) referenced in function
"public: bool __thiscall CPwServer::Connect(class
ATL::CStringT > >,unsigned long,unsigned long *)"
(?Connect#CPwServer##QAE_NV?$CStringT#_WV?$StrTraitMFC_DLL#_WV?$ChTraitsCRT#_W#ATL#####ATL##KPAK#Z)
And this is the call I use to access the DLL.
bool conn = PwSrv->Connect(_T(""));
Dumpbin Export of the function :
25BE6 ?Connect#PwServer##QAE_NPBGKPAK#Z 25BE6 __imp_?Connect#PwServer##QAE_NPBGKPAK#Z
Is there something else which needs to be dine in case of linking a MFC DLL with a regular one, like adding AFX_EXT_ or something?
Kindly advise in this.
Thank you.
UPDATE
Seems all that was required was to toggle the flag set in Project Properties>>C/C++>>Language>>Treat wchar_t as a built in type to NO. I'd never bothered with the flag before, so didn't know. The Linker error was there...
OK. Now I've another problem. The toggling of wchar_t solved the problem of the DLL linking with another MFC DLL, but now my application cannot find the entry point in my DLL. In dependency walker, it shows a mismatch between CString which the application is sending, and the Unsigned Short..which my DLL is accepting ( as a result of thewchar_t turned off, presumably )
Assuming you correctly included the .lib file for the DLL (most of the time this is down to differences in the compiler settings. e.g. UNICODE setting).
Check that the .lib is actually being loaded by setting the 'Show Progress' Linker settings to VERBOSE.
Run DUMPBIN on the LIB file to check that the exported functions are the same as the ones the linker is trying to import.
ie
dumpbin /ALL mylib.lib > exports.txt
If the name decoration is slightly different that'll give you a clue as to the problem.

Building and linking test code for Crypto++

I'm trying to write some simple test code for the Crypto++ library for a project. I have yet to manage to get my own code to build though. It compiles fine, the problem comes in linking. I'm still pretty new to Visual Studios, but I'm using VS10. The errors I'm getting are:
1>sec_test.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall CryptoPP::DES::Base::ProcessAndXorBlock(unsigned char const *,unsigned char const *,unsigned char *)const " (?ProcessAndXorBlock#Base#DES#CryptoPP##UBEXPBE0PAE#Z)
1>sec_test.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall CryptoPP::DES::Base::UncheckedSetKey(unsigned char const *,unsigned int,class CryptoPP::NameValuePairs const &)" (?UncheckedSetKey#Base#DES#CryptoPP##UAEXPBEIABVNameValuePairs#3##Z)
I've tried everything I can find in the documentation in terms of linking. I've never linked against a DLL before, but these are the errors I get when I try to. If I try to do what I think is linking against the static library version, I get even more.
I should note, I'm trying to test pure DES at the moment. In particular, here are the API calls I'm making, just to be safe:
DES::Encryption DES_encrypt;
DES_encrypt.SetKey(key, 64);
DES_encrypt.ProcessAndXorBlock(plaintext, NULL, ciphertext);
DES::Decryption DES_decrypt;
DES_decrypt.SetKey(key, 64);
DES_decrypt.ProcessAndXorBlock(ciphertext, NULL, decrypted);
If anyone can help, or point me in the right direction, I'd be much obliged.
First thing to check is your project properties (right click on project, click Properties).
External libraries need to be specified in the Linker->Input->Additional Dependencies field, either by absolute path or in conjunction with the other VS path properties.
You can look in Linker->Command Line and check that the .lib files you want are actually being passed to the linker.
An alternate method is to turn off the Suppress Startup Banner option in the Linker->General options, and then check the build output to make sure it has what you want.
If you know that the libraries you want are being linked, another useful trick is to check the output of the strings command (in linux or cygwin) or dumpbin /HEADERS in the VS command prompt. You can look through the output of these commands for the symbol VS claims is missing to verify that it really is defined in the .lib file. Sometimes larger software packages have multiple .lib files, so this can help make sure you are linking the one that has the symbol you want.

DLL and Name Mangling

I have a third-party LIB which has symbols exported as plain C/cdecl, so for example dumpbin.exe /SYMBOLS reports that both __imp_nvmlInit and nvmlInit are exported.
However in Visual Studio 2010 when I try to import them, the header file will have
extern "C" nvmlReturn_t nvmlInit(...);
but when I try to compile, I get the following error:
main.obj : error LNK2019: unresolved external symbol _nvmlInit referenced in function _main
How can I stop Visual Studio from looking for that symbol with a leading underscore? __declspect(dllimport) doesn't work because then it decorates to __imp__nvmlInit (one underscore too many).
Thanks.
That is a linker error. You need to link with the .LIB file associated with DLL, which will give the linker a promise that the function will be available at run-time when the DLL itself is loaded.

Using a DLL that links to a static lib

I'm trying to build a solution in Visual C++ where I have a front-end project that references a DLL project that I created. In the DLL project I link to a static library (that I have not written) that has static objects and definitions. Everything builds fine but I have linking problems.
I have a couple of questions. First, I should only get unresolved symbols for objects that I reference in the front-end that are not exported, right? I want the DLL to be the only interface to the static library and do not directly reference any part of it in the front-end, and yet I get a number of unresolved symbols from this library. There symbols seem to be #included and at least some not directly linked by the DLL project. I suspect it has to do with the static declarations in the static lib but how can I deal with these?
Some of the unresolved symbol errors:
2>AnalysisVis.obj : error LNK2001: unresolved external symbol "public: __thiscall SharkException::SharkException(char const *,int,char const *)" (??0SharkException##$$FQAE#PBDH0#Z)
2>AnalysisVis.obj : error LNK2001: unresolved external symbol "public: static class Bernoulli Rng::coinToss" (?coinToss#Rng##2VBernoulli##A)
2>AnalysisVis.obj : error LNK2001: unresolved external symbol "public: virtual bool __thiscall ChromosomeT<bool>::operator<(class Chromosome const &)const " (??M?$ChromosomeT#_N##$$FUBE_NABVChromosome###Z)
The exported symbols are mangled. If the static lib was compiled using a different compiler (or compiler version) than the one you are using, it is possible that the symbols your application is expecting to see were defined in the static lib using a different name mangling scheme. You can use the following command to get the name mangling used in the static lib and then compare it to the one in the error message:
>pushd <path_to_msvc_dir>\Microsoft Visual Studio X.0\VC\bin
>dumpbin /all [static_lib_path] > out.txt
>type out.txt | find /I "SharkException"
>type out.txt | find /I "coinToss"
>type out.txt | find /I "ChromosomeT"
BTW, does the DLL that uses the static lib compiles cleanly with the same compiler your application/solution does?