Linker error with debug build with different compiler versions - visual-studio

We have a DLL, built with MS Visual Studio 2010, in release mode. We provide this DLL to different customers, along with a .lib file. The functions in the DLL are exported with:
extern "C" __declspec(dllexport) int analyze(int id);
Our customers have two applications that makes use of this DLL. Both of these applications import the DLL functions using:
extern "C" __declspec(dllimport) int analyze(int id);
One of these applications is built with MS Visual Studio 2010. This application can be built successfully in both debug and release modes.
The other application must unfortunately use MS Visual Studio 2005 as its build environment. In this application, the release build can be built successfully, however, when we try to build in debug mode, we get linker errors:
LNK2019: unresolved external symbol __imp_analyze referenced in function "void __cdecl process(char const *,char const *)" (?process##ABCERFG0#Z)
Can someone help me understand what we are missing here? Are we exporting the functions in a manner that is not portable across compilers? What's the solution?
Regards,

The .obj file format is highly conserved between VS2005 and VS2010. This should not be a problem, especially since it is a simple non-mangled symbol reference. And especially not when it works in the Release configuration but not in Debug. A simple explanation is always better than a convoluted one: your customer simply forgot to add your .lib file to the linker's Additional Dependencies setting.
Beware that the setting change needs to be made for both configurations, use the "Configuration" combo in the upper left corner of the dialog.
You can help your customer fall into the pit of success by using #pragma comment(lib, "mumble.lib") in your .h file.

Related

MSVC 2019: libc externals in legacy library not resolved

I am porting a legacy app (originally compiled with VC 6.0) to MSVC 2019. It uses a legacy static library (libtest.lib), compiled with VC 6.0. My problem is that some (but not all) standard libc functions in libtest.lib are not being resolved by MSVC 2019.
For example, libtest.lib uses vsprintf(). On compilation MSVC 2019 reports "unresolved external symbol _vsprintf referenced in ...". Other libc functions (e.g. strlen) are resolved just fine.
I've tried mucking with a gazillion build settings with no joy.
Why is this happening and how can I fix it?
My research so far...
I did a lot of digging in the VC60 headers and found that vsprintf is defined in studio.h as
_CRTIMP int __cdecl vsprintf(char *,const char *, va_list);
while strlen in defined in string.h
as
size_t __cdecl strlen(const char *);
I'm not sure of the implications but I'm guessing that strlen is just a plain-vanilla static function while vsprintf is imported from some CRT DLL (which is probably different in MSVC 2019).
I guess I could port libtest.lib to MSVC 2019 too, but I've got close to 100 other static libraries and porting them all would be a major pain in the butt.
Thanks to #dewaffled for this great answer:
Microsoft has a library to adapt CRT functions to the latest versions of MSVC e.g., 2019
Simply add the following line to your main program:
#pragma comment(lib, "legacy_stdio_definitions.lib")
Alternatively, I think you can add the library to:
Project Properties -> Linker -> Input -> Additional Dependencies

How to configuring NTL library in Visual Studio 2017

I have just installed Visual Studio 2017 and I want to use the NTL library. I have followed the steps described here (for VS2013). Compiling NTL library in Visual Studio 2013
As expected, it compiles (with several, I hope, negligible warnings).
Then, under the same solution, I am doing these consecutive steps:
(under the same solution)
Add project -> New project -> Visual C++ -> Win32 Console Appl.
Right click on the created project -> Set as StartUp Project
Right click on the created project -> Add -> Reference -> NTL
Right click on the created project -> Configuration Properties ->
C/C++ -> General -> Additional Include Directories -> (NTL includes)
Take/copy some file from folder "tests" (downloaded from the NTL
repository)
Remove everything below #include "stdafx.h"
Paste and build
Those steps should work on VS2013 & VS2015, unfortunately when I build I got 4 linker related errors (LNK2019).
They all are similar to the example below:
Error LNK2019 unresolved external symbol "void __cdecl
NTL::MatPrime_crt_helper_deleter(class NTL::MatPrime_crt_helper *)"
(?MatPrime_crt_helper_deleter#NTL##YAXPAVMatPrime_crt_helper#1##Z)
referenced in function "public: static void __cdecl
NTL::ZZ_pInfoT::MatPrime_crt_helper_deleter_policy::deleter(class
NTL::MatPrime_crt_helper *)"
(?deleter#MatPrime_crt_helper_deleter_policy#ZZ_pInfoT#NTL##SAXPAVMatPrime_crt_helper#3##Z) NTLtest <thePathToTheLib>
(ZZ_p.obj) 1
Can you advice how to proceed?
I have tried to built this example -> ZZ_pEXTest.cpp
Thank you in advance!
First, I am assuming you get the same 4 errors I do. I get the one you showed in your question, plus three more. In all cases, it involves a forward declaration of a method or function that does actually exist in the code.
However, the types in the declarations are classes and the types in the implementation are structs. The function signature is therefore not the same and the linker can't find the implementation.
So, I simply updated the the forward declarations of the parameter types to be what they should be: structs.
In lip.h, change _ntl_general_rem_one_struct to be a struct.
In ZZ_p.h, change MatPrime_crt_helper to be a struct.
I believe this is all I did.
You shouldn't really have to make changes to the code. There may be a compiler switch, or it only fails in VS. I don't know. All I know is it is written by someone a lot smarter than me, and life is too short; I've made my changes and I'm moving on.

Unresolved external symbol __vsnprintf .... (in dxerr.lib)?

I am running a DirectX 11 application on windows 7 and visual studio community 2015 RC. I'm still using functions from the DX SDK. It worked fine on VS2013 but when I switched over I get only the following error:
Error LNK2019 unresolved external symbol __vsnprintf referenced in function "long __stdcall StringVPrintfWorkerA(char *,unsigned int,unsigned int *,char const *,char *)" (?StringVPrintfWorkerA##YGJPADIPAIPBD0#Z) Ancora D:\Moody\Moody\Projects\Projects\Ancora\Ancora\dxerr.lib(dxerra.obj) 1
I only use the DXGetErrorDescriptionA function from the dxerr library and when I comment it out, the program compiles fine. I have no idea what's wrong but it can't be from the DX SDK or otherwise the other functions would fail right?
I experienced the same problem using DXGetErrorMessage() with Dx9 and found out that MS have provided an additional library to include in the Additional Dependencies properties page to address this problem. The library name is: legacy_stdio_definitions.lib
Adding this resolved the issue for me.
just add
#pragma comment(lib, "legacy_stdio_definitions.lib")
https://msdn.microsoft.com/en-us/library/bb531344.aspx
Instead of hacking dxerr.lib manually, you could add
#include <Windows.h>
#include <stdio.h>
int (WINAPIV * __vsnprintf)(char *, size_t, const char*, va_list) = _vsnprintf;
somewhere in your code
The legacy DirectX SDK is quite old, and dxerr.lib in the DXSDK is not compatible with VS 2015's C Runtime as you have encountered.
In general static libraries with code in them don't mix well from different versions of the compiler. Most of the .libs in the legacy DirectX SDK work with VS 2015 because they are import libraries for dlls or all data libraries and therefore contain no code at all. The DXSDK has not been updated since VS 2010.
Aside: The VS team has made a heroic effort to keep the Visual C/C++ Runtime link compatible between VS 2015 Update 3, VS 2017, and VS 2019 per Microsoft Docs. This is not the normal pattern.
Be sure to read the instructions on Microsoft Docs on the proper way to mix the legacy DirectX SDK with the Windows 8.x SDK used by VS 2015. You are presumably using something else from the legacy DirectX SDK in this project besides dxerr.
I have implemented a version of DXERR that you can build from source in your project to remove this dependency of the legacy DirectX SDK. See this post for details. That said, I purposely only supported Unicode (the W version). You can work out how to make the ANSI (the A version) easily enough, but it would be best if updated your app to use Unicode.
See Where is the DirectX SDK (2021 Edition)? and DXUT for Direct3D 11.
UPDATE: As noted in another answer linking with legacy_stdio_definitions.lib should make the old legacy DirectX SDK version of dxerr.lib link again with VS 2015/2017. That said, you should work on removing dependencies on the legacy DirectX SDK as much as possible and DXERR is easily replaced by your own module. See Living without D3DX.
The DirectX libraries you are using are compiled with an older version of Visual Studio than you are using. Microsoft sometimes makes changes to their C runtime, creating incompatibilities between libraries compiled with different versions. __vsnprintf was an internal symbol in older versions of their C runtime, it does not exist in the 2015 RC version.
Unfortunately, dxerr.lib (along with d3dx11.lib) have been deprecated. You have two options - you can switch back to VS2013 or you can stop using functionality from dxerr.lib. The latter is probably better, because you can duplicate its functionality by using FormatMessage now (more info in the linked article).
HACKY but you could patch dxerr.lib.
Replace __vsnprintf with _vsnprintf (with a null at the end to account for the removed underscore at the beginning)
You can change the Platform Toolset from Visual Studio 2015 to Visual Studio 2013 and then it compiles.
The Platform Toolset is found on the General tab of the Project Properties.

Qt, VC 2010 and static libraries

I need to use a static library in my Qt5 project. I'm using VC++ 2010 as my compiler and QtCreator as IDE.
If I use the dynamic version (.DLL) everything works fine.
If I try to use the static version (.LIB) it seems like the library is looking for other dependencies that can't be satisfied.
Sadly, using the DLL is not an option for my project.
The point is that if I try to use the static library from VC++ IDE everything works fine.
Please note that I can use other VC++ headers without any problem in my Qt project.
It seems like the compiler can find everything it needs (basically, my source code and all the required headers) while the linker is missing something.
error: LNK2019: unresolved external symbol _imp_SystemTimeToVariantTime#8 referenced in function "bool __cdecl SystemTimeToMinute(struct _SYSTEMTIME *,unsigned long *)" (?SystemTimeToMinute##YA_NPAU_SYSTEMTIME##PAK#Z)
SystemTimeToVariantTime is defined in OleAut32.lib.
Am I wrong expecting the linker to automatically look for needed libraries and headers based on the content of the global variables INCLUDE and LIB?
Solved.
The problem was that I was trying to include external (SDK) libraries using
LIBS += -l OleAut32.lib
While I had to simply use
LIBS += OleAut32.lib
Well, problem solved.
I hope this can help someone in the future!

Visual Studio 2010 C++: How to tell which LIB files the linker actually tries to link?

I am working on an (unmanaged) x64 Win32 C++ application in Visual Studio 2010 Pro, and keep getting a strange linking error.
This application makes use of the LoadImage() Windows API function through including windows.h. While the application compiles fine in the Release configuration (and LoadImage() does its job), I cannot get the executable linked in the Debug configuration. I keep getting this error:
Redacted.obj : error LNK2019: unresolved external symbol __imp_LoadImageW referenced in function "public: int __cdecl Redacted::Redacted::Execute(void)" (?Execute#Redacted#Redacted##QEAAHXZ)
C:\Users\redacted\Documents\Visual Studio 2010\Projects\Redacted\x64\Debug\Redacted.exe : fatal error LNK1120: 1 unresolved externals
If I switch from Unicode to non-multi-byte character set, the error message will change from LoadImageW() to LoadImageA() accordingly, but otherwise persist. As I cannot find any relevant differences in the properties for the Release and Debug configuration, I am at a loss why it will compile in one, but not the other. User32.lib is correctly set as an Additional dependency for the Linker in both configurations, and the /MACHINE:X64 flag is set in both as well.
Since the linker doesn't complain about not finding the User32.lib, I am led to believe that it tries to link a wrong version from the Platform SDK, i.e. the 32-bit one. But how can I find out which exact copy of a LIB file the linker actually tries to use?
Check the linker paths in the global configuration settings. Most probably one of those is wrong.
Beyond that, I believe there's a linker /VERBOSE flag (or something similar) which will display the information you're looking for. It's somewhere in the linker settings for the project you're building.

Resources