Unresolved external symbol __vsnprintf .... (in dxerr.lib)?
Asked Answered
T

7

55

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?

Tantalous answered 25/6, 2015 at 14:47 Comment(0)
C
98

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.

Cherriecherrita answered 11/12, 2015 at 18:24 Comment(3)
I vote for this.Thanks LaurieW. And additional article can be found here:msdn.microsoft.com/en-us/library/bb531344.aspxEyecup
Once again, thank God for StackOverflow. Is it asking too much that Microsoft would mention this on the "_vsnprintf" Web page?Licko
There is also an MS Overview of potential upgrade issues (Visual C++) that covers this library.Ballou
B
31

just add

#pragma comment(lib, "legacy_stdio_definitions.lib")

https://msdn.microsoft.com/en-us/library/bb531344.aspx

Bridgettbridgette answered 21/3, 2018 at 5:47 Comment(3)
Excactly what I need, being hindered by this problem for months. Learning the most updated SDK is not newbie friendly. Thanks a lot.Shelba
The link in this answer now redirects to learn.microsoft.com/en-us/cpp/porting/… - but despite having three uses of #pragma comment I'm not sure how it relates to this question. I checked archive.org copies of the original page but couldn't find #pragma comment on any of them.Alysa
@AJM: You need to search for legacy_stdio_definitions.lib. There is also an MS Overview of potential upgrade issues (Visual C++) that covers this library.Ballou
T
24

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

Thitherto answered 23/10, 2015 at 0:7 Comment(2)
It's worth noting this should be done in a compiler unit rather than a header file. Also if you're building in a Unicode character set environment, this is going to require int (WINAPIV * __vsnwprintf)(wchar_t *, size_t, const wchar_t*, va_list) = _vsnwprintf; instead.Notochord
I tried that and no longer get the error but now I get C2065 '_vsnprintf': undeclared identifierRennet
T
6

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.

Throckmorton answered 23/10, 2015 at 1:6 Comment(0)
T
5

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).

Treaty answered 26/6, 2015 at 12:47 Comment(1)
A third option is to build your own dxerr.Throckmorton
E
3

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)

Engleman answered 2/10, 2015 at 19:38 Comment(0)
C
2

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.

Contradiction answered 28/8, 2016 at 21:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.