Updated Visual Studio, now wxWidgets complains about unresolved symbols - c++

Problem description:
I have a Visual Studio 2012 C++ project which uses wxWidgets. It compiles and links perfectly.
For reasons we won't go into, I now need to make this work with Visual Studio 2015.
Having twiddled the settings and got all the code to compile, it now refuses to link because all the libraries it uses are compiled for VS 2012. OK...
I replaced all the libraries with ones compiled for VS 2015. Everything works again... except wxWidgets.
I have now spent multiple days fruitlessly trying to force wxWidgets to work. It just won't do it.
Here's what I've done so far:
Looking at the instructions at https://github.com/wxWidgets/wxWidgets/releases/, it appears I'm supposed to download and unpack two files:
wxWidgets-3.1.1-headers.7z (which contains an include folder)
wxMSW-3.1.1_vc140_Dev.7z (which contains a lib folder).
I deleted the old wxWidgets stuff, and unpacked these two new zips.
Hundreds of preprocessor errors saying it can't find some include file. It looks like the old directory structure had ...\lib\vc_lib\... rather than ..\lib\vc140_dll\..., so I tried renaming the folder. Now everything compiles successfully.
Next the linker complains that it can't find wxbmsw28ud_core.lib — which makes sense, considering I just deleted it. I changed all the filenames to be *31 rather than *28, and no more file-not-found errors.
Now I have hundreds of LNK2001 errors. For example:
Error LNK2001 unresolved external symbol "protected: static struct wxEventTable const wxDialogBase::sm_eventTable" (?sm_eventTable#wxDialogBase##1UwxEventTable##B)
I don't understand this though. If I run DumpBin.exe against wxmsw31ud_core.lib, it dumps out several megabytes of text, including:
5146A2 __imp_?sm_eventTable#wxDialogBase##1UwxEventTable##B
and also
29C0 __imp_?sm_eventTable#wxDialogBase##1UwxEventTable##B
and also
Version : 0
Machine : 14C (x86)
TimeDateStamp: 5A8A0543 Sun Feb 18 22:59:15 2018
SizeOfData : 00000049
DLL name : wxmsw311ud_core_vc140.dll
Symbol name : ?sm_eventTable#wxDialogBase##1UwxEventTable##B (protected: static struct wxEventTable const wxDialogBase::sm_eventTable)
Type : data
Name type : name
Hint : 14306
Name : ?sm_eventTable#wxDialogBase##1UwxEventTable##B
In other words, the exact symbol that VS says it can't find!
So if the symbol is in the .lib file and I can see it there, why is VS complaining that it's not in the .lib file?
Just to be 100% certain, I made a table of every single symbol that VS claims it can't find and which .lib file it's actually in:
LNK2001 ?sm_eventTable#wxDialogBase##1UwxEventTable##B wxmsw31ud_core.lib
LNK2001 ?wxTheAssertHandler##3P6AXABVwxString##H000#ZA wxbase31ud.lib
LNK2001 ?wxTrapInAssert##3_NA wxbase31ud.lib
LNK2001 ?wxConvLibcPtr##3PAVwxMBConv##A wxbase31ud.lib
LNK2001 ?wxEmptyString##3PB_WB wxbase31ud.lib
LNK2001 ?npos#wxString##2IB wxbase31ud.lib
LNK2001 ?sm_first#wxClassInfo##0PAV1#A wxbase31ud.lib
LNK2001 ?wxNullBitmap##3VwxBitmap##A wxmsw31ud_core.lib
LNK2001 ?wxNullIcon##3VwxIcon##A wxmsw31ud_core.lib
LNK2001 ?wxDefaultSize##3VwxSize##B wxmsw31ud_core.lib
LNK2001 ?wxDefaultPosition##3VwxPoint##B wxmsw31ud_core.lib
LNK2001 ?wxEVT_NULL##3HB wxbase31ud.lib
LNK2001 ?wxEVT_BUTTON##3V?$wxEventTypeTag#VwxCommandEvent####B wxmsw31ud_core.lib
LNK2001 ?wxDefaultValidator##3VwxValidator##B wxmsw31ud_core.lib
LNK2001 ?wxButtonNameStr##3QBDB wxmsw31ud_core.lib
LNK2001 ?ms_classInfo#wxDialog##2VwxClassInfo##A wxmsw31ud_core.lib
LNK2001 ?wxStaticTextNameStr##3QBDB wxmsw31ud_core.lib
LNK2001 ?wxListCtrlNameStr##3QBDB wxmsw31ud_core.lib
LNK2001 ?wxConvUTF8Ptr##3PAVwxMBConvStrictUTF8##A wxbase31ud.lib
LNK2001 ?ms_appInitFn#wxAppConsoleBase##1P6APAVwxAppConsole##XZA wxbase31ud.lib
LNK2001 ?ms_appInstance#wxAppConsoleBase##1PAVwxAppConsole##A wxbase31ud.lib
LNK2001 ?ms_idMainThread#wxThread##0KA wxbase31ud.lib
LNK2001 ?wxEVT_CLOSE_WINDOW##3V?$wxEventTypeTag#VwxCloseEvent####B wxmsw31ud_core.lib
LNK2001 ?wxEVT_SIZING##3V?$wxEventTypeTag#VwxSizeEvent####B wxmsw31ud_core.lib
LNK2001 ?wxEVT_COMMAND_ENTER##3V?$wxEventTypeTag#VwxCommandEvent####B wxmsw31ud_core.lib
LNK2001 ?wxTextCtrlNameStr##3QBDB wxmsw31ud_core.lib
LNK2001 ?wxGaugeNameStr##3QBDB wxmsw31ud_core.lib
LNK1120 28 unresolved externals
As you can see, every single symbol is listed in either wxmsw31ud_core.lib or wxbase31ud.lib, which are both configured in the project (along with several additional wxWidgets libraries as well).
I don't understand what the problem is. I don't get why it's complaining at me. But I need to make this work. Any suggestions?

Mixing compiled files from different VS versions will lead to errors ("not found" or "incompatible") in the linking stage. Also, mixing 32/64 versions will fail.
Delete (or move to a different dir) all of [old] wxWidgets stuff, specially the generated dirs and objects during a previous wxWidgets building.
Download current wxWidgets sources from official page, or the Windows installer.
Build using the proper VS solution. Taken from wxdir\docs\msw\install.txt:
Ready to use project files are provided for VC++ versions 7, 8, 9, 10,
11, 12, 14 and 15 (also known as MSVS 2003, 2005, 2008, 2010, 2012,
2013, 2015 and 2017 respectively).
Simply open wx_vcN.sln (for N=7, 8, 9, 10, 11, 12, 14, or 15) file,
select the appropriate configuration (Debug or Release, static or DLL)
and build the solution. Notice that when building a DLL configuration,
you may need to perform the build several times because the projects
are not always built in the correct order, and this may result in link
errors. Simply do the build again, up to 3 times, to fix this.
So, simply open wx_vc14.sln and build your solution. It seems you want static library, so wx gets embedded into your app; if not, select the DLL solution.
Notice that in that wxWidgets download page you can directly get the headers and the static ("Development") or dynamic ("Release DLL") already compiled files, so as to avoid wxWidgets compilation itself.

Your link error is due to the linker looking for the function in a static library, while you're linking with DLL import libraries. IOW when you write
In other words, the exact symbol that VS says it can't find!
it is just wrong because there is clearly a difference: one symbol has the __imp__ prefix and the other one doesn't.
Either rebuild your application with WXUSINDLL defined or link with static wx libraries.
And, honestly, all of us make mistakes and it may happen that you spend hours or even days on something that can be solved in minutes, but blaming your tools really doesn't help when the problem is not with them.

On top of a great help from Vadim and Ripi2, I think you are also trying to upgrade wxWidgets from version 2.8 to 3.0. This is in itself a huge task and you should consider do one properly then the other.
I'd start with the building 2.8 source statically with the compiler at hand and then try to ujpgrade the version of wxWidgets very carefully.
Thank you.

I eventually gave up and attempted to build wxWidgets from source.
It took many, many attempts, but eventually I was able to compile wxWidgets in such a way that my application now builds successfully. It seems you have to check that all the hundreds of thousands of compilation settings in VS are identical to the target application. No, it doesn't seem to be possible to automate that.
(Having said all that, compared to how nightmarishly difficult it usually is to build anything C-related from source, this was comparatively easy...)

Related

C++: Unresolved external symbol _sprintf and _sscanf in Visual Studio 2015

For a research project, I'm writing a C++ add-on to a scientific computing language. Unfortunately the library that allows users to do this is not kept very well up-to-date.
I started the project in XCode, where it built fine. Later I had to move to a PC, so I migrated the code to Visual Studio 2015. Since doing this, I haven't been able to build due to the following errors:
LNK2001 : unresolved external symbol _sprintf
LNK2019 : unresolved external symbol _sscanf referenced in function _GetDDouble
LNK2019 : unresolved external symbol _sprintf referenced in function _CheckRunningInMainThread
An attempted fix was to add the header #define _CRT_SECURE_NO_WARNINGS. However, this a) fixed no errors and b) added the warning C4005 : '_CRT_SECURE_NO_WARNINGS': macro redefinition. I assume the library already defined this macro, anticipating this problem. Regardless, it didn't solve the problem.
How should I proceed?
Add the following library to the linker input files:
legacy_stdio_definitions.lib
VS 2015 now uses inline definitions that call internal functions for many of the stdio.h functions. If an object file (or library member) depends on one of those functions, then the legacy_stdio_definitions.lib provides an externally linkable version of the function that can be linked to.
Your other option is to recompile the unit that depends on those functions with VS 2015 (this is probably the preferred option).
I got this error compiling cycling max plugins against version 5 max sdk (pure c api). The legacy library fix didn't work for me (it should have, and if anyone had any idea why it mightn't I'd be curious), but I defined _NO_CRT_STDIO_INLINE before stdio was loaded and that did do the trick.
I recently encountered this and was able to add User32.lib to Linker > Input > Additional Dependencies.
You could also include #pragma comment (lib, "User32.lib") in your code.

SFML and VS2013 - WinMain/main linker error

I am trying to use SFML with Visual Studio 2013 using the tutorial on the SFML website and using their sample code (replacing main() with WinMain()) but I'm getting the linker error:
Error 1 error LNK2019: unresolved external symbol _main referenced in function _WinMain#16
I am referencing the libs:
sfml-graphics-d.lib
sfml-window-d.lib
sfml-main-d.lib
sfml-system-d.lib
and I am pointing correctly to the 'include' and 'lib' folders in my Project Properties.
I have tried using 'main()' with sfml-main-d.lib referenced and 'WinMain()' without it referenced and I still get the linker error.
Any suggestions?
Thank you for your time
Okay I seem to have solved it but don't know how. I'll do my best to explain to anyone else who is stuck:
I started a new project again with a fresh download of SFML 32-bit for VS2013.
I added sfml-main-d.lib and sfml-main.lib to my referenced libs (for debug and release respectively) and then use "int main()..." instead of "int __stdcall WinMain()" and it linked and compiled correctly.
I thought I had already tried this combination but I guess maybe not.
Thanks to anyone who took the time to read this question and to Elried for commenting.

Link against a 3rd-party library with Visual Studio

I'm trying to create a .dll with Visual Studios 2013. The project includes libpq functionality.
Per other stackoverflow posts, and other sources I've found on the internet, I've (as far as I'm aware) correctly added the postgres lib and include directories to the project. However, when I go to build the project, it returns a number of "unresolved external symbol" errors.
My paths are C:\Program Files\PostresSQL\9.3\... so I have them surrounded by quotation marks in the Additional Library/Include Directory fields. I've included the libpq-fe.h header file in the project... I'm just not sure what I'm doing wrong.
Another note, I can compile a test program from the command line using g++ with the -I, -L, and -lpq flags, but I'm not sure how to compile to a .dll from the command line (plus it adds complexity that I just don't want to deal with).
These are the specific errors I'm getting:
1>sql_arma.obj : error LNK2001: unresolved external symbol _PQconnectdb
1>sql_arma.obj : error LNK2001: unresolved external symbol _PQstatus
1>sql_arma.obj : error LNK2001: unresolved external symbol _PQerrorMessage
1>sql_arma.obj : error LNK2001: unresolved external symbol _PQfinish
1>C:\Users\tills13\documents\visual studio 2013\Projects\sql_arma\Release\sql_arma.dll : fatal error LNK1120: 4 unresolved externals
I have, as suggested below, included #pragma comment(lib, "libpq.lib") in the source file for my project, I still receive these errors.
I've successfully compiled the sample program by setting these project properties:
Add <pgsql install path>\include and \lib to VC++ Directories->Include and ->Library, correspondingly
Add libpq.lib to Linker->Input->Additional dependencies
This is the standard way to reference 3rd-party libs. It's just that they recommend using environment variables for their "base dirs" to avoid patching the project when it's under a VCS.
To be able to run the app from VS (both with and without debugging), I also specified PATH=%PATH%;<pgsql install path>\bin in Debugging->Environment since this dir isn't in PATH on my system.
It's not sufficient add the postgres lib directory to the project, you must also add
reference to libpq.lib. Just add this line to one of your source .cpp files:
#pragma comment(lib, "libpq.lib")
As noted by Marco A. the library must match a program bitness (32 or 64 bit): if you build 32-bit DLL (referred as Win32) you must use 32 bit library; if 64-bit (x64) - 64-bit library.
I have also faced same issue. Then I realized that I was building my application as a 32bit. I changed the target of my application to x64 and it compiled successfully

Linker error while linking some windows APIs

I have a makefile project in my system. Recently, I added some new functions which makes use of the following Windows APIs:
RegOpenKeyEx
RegEnumKeyEx
RegCloseKey
RegGetValue
For having those APIS I added the windows.h header file as well.
The code compiles and links fine in my machine. But, linking fails in my colleagues machine. We all are working on 64 bit windows machine.
In his PC I get the error:
error LNK2001: unresolved external symbol __imp_RegOpenKeyExW
error LNK2001: unresolved external symbol __imp_RegGetValueW
error LNK2001: unresolved external symbol __imp_RegCloseKey
error LNK2001: unresolved external symbol __imp_RegEnumKeyExW
What I tried:
Since the library being used was Advapi32.lib in C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Lib\x64
I tried adding following line:
LINKFLAGS += -L "C:\Program Files (x86)\Microsoft
SDKs\Windows\v7.0A\Lib\x64"
I added the path of the library to environment variable PATH
I copied the lib to the output folder.
Nothing worked.
As I said earlier, the code works fine in my PC but fails in another one.
The registry functions require you to pass Advapi32.lib to the linker. This is the step that you have missed.
If you are using visual stdio, check your project property vs your friend's project property and check link library path+ library name with .lib shoul be included. It seems in your friends computer is not getting the library to resolve the symbols. Compile time checking is done only with header files. While linking it should find the definition of yor function in library.
for command line:
from:http://social.msdn.microsoft.com/Forums/vstudio/en-US/6bcae3d1-85b6-471d-a4ee-7b455b21460b/how-do-i-link-libraries-that-are-sitting-in-different-directories-from-the-command-line?forum=vcgeneral
cl main.obj ab1.lib ab2.lib de1.lib de2.lib gh1.lib /Fetestmain.exe /link /LIBPATH:C:\test\ab /LIBPATH:C:\test\de /LIBPATH:C:\test\gh
The "/link" is very important...do not use "/LINK", the uppercase LINK is not recognised.

Unresolved external symbol - IdnToAscii

I tried to build the following sample application available on msdn:
http://msdn.microsoft.com/en-us/library/windows/desktop/dd319089%28v=vs.85%29.aspx
I created a new C++ command line project in Visual Studio 2012 Premium on a windows 7 64bit box, and copied the code of the sample in the main cpp file.
When I try to compile, I get the following error:
Error 1 error LNK2001: unresolved external symbol __imp__IdnToAscii#20
From other posts of people having similar errors, I figure I'm supposed to include some header or lib file. But which one(s)? How do I do that in VS2012/C++ (I'm a complete c++ noob...)
It seems from MSDN, you need to link against Normaliz.dll.
Try adding Normaliz.lib in Linker -> Input -> Additional Dependencies