未解决的外部符号__vsnprintf....(在dxerr.lib中)?

52

我正在Windows 7和Visual Studio Community 2015 RC上运行一个DirectX 11应用程序。我仍在使用来自DX SDK的函数。在VS2013上它可以正常工作,但是当我切换到新的版本后,只会收到以下错误:

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

我只使用dxerr库中的DXGetErrorDescriptionA函数,当我将它注释掉时,程序可以编译通过。我不知道哪里出了问题,但如果是来自DX SDK的话,其他函数也会失败,对吧?

7个回答

93
我使用 DXGetErrorMessage() 遇到了与使用 Dx9 相关的的同样问题,并发现微软提供了一个额外的库文件,需要在 Additional Dependencies 属性页中包含该库以解决此问题。该库的名称为:legacy_stdio_definitions.lib
添加该库使我成功解决了此问题。

4
我支持这个。感谢LaurieW。您可以在此处找到附加文章:https://msdn.microsoft.com/en-us/library/bb531344.aspx - SONIC3D
5
再一次,感谢StackOverflow。微软能否在"_vsnprintf"网页上提及一下这个呢?请问这样做是否过分要求? - Pierre
还有一个MS 潜在升级问题概述(Visual C++),涵盖了这个库。 - MattTT

29

正是我所需要的,被这个问题困扰了几个月。学习最新的SDK并不适合新手。非常感谢。 - timhu
此答案中的链接现在重定向到 https://learn.microsoft.com/en-us/cpp/porting/visual-cpp-change-history-2003-2015?redirectedfrom=MSDN&view=msvc-170 - 但尽管有三个 #pragma comment 的用法,我不确定它与这个问题有什么关系。我检查了原始页面的 archive.org 副本,但没有在任何副本中找到 #pragma comment - AJM
1
@AJM:你需要搜索legacy_stdio_definitions.lib。还有一个微软的Visual C++潜在升级问题概述也涵盖了这个库。 - MattTT

23

你可以添加代码而不是手动修改dxerr.lib

#include <Windows.h>
#include <stdio.h>
int (WINAPIV * __vsnprintf)(char *, size_t, const char*, va_list) = _vsnprintf;

你的代码中某个地方


1
值得注意的是,这应该在编译器单元中完成,而不是头文件中。此外,如果您正在构建Unicode字符集环境,则需要使用int (WINAPIV * __vsnwprintf)(wchar_t *, size_t, const wchar_t*, va_list) = _vsnwprintf; - Vinz
我尝试了那个方法,不再出现错误,但现在出现了C2065'_vsnprintf':未声明的标识符。 - Robert Stevens

5
传统的DirectX SDK相当古老,DXSDK中的dxerr.lib与VS 2015的C运行时不兼容,这是您遇到的问题。通常情况下,带有代码的静态库不适用于来自不同版本编译器的混合使用。传统的DirectX SDK大多数.libs与VS 2015兼容,因为它们是dll的导入库或所有数据库,因此根本不包含任何代码。DXSDK自VS 2010以来未更新。
引用:“此外:根据Microsoft Docs,VS团队已经做出了英勇的努力,使Visual C/C++运行时链接在VS 2015 Update 3、VS 2017和VS 2019之间保持兼容。这不是正常的模式。”
请务必阅读Microsoft Docs上有关在VS 2015中正确混合遗留DirectX SDK和Windows 8.x SDK的说明。您在这个项目中使用了遗留DirectX SDK中除了dxerr之外的其他内容。
我已经实现了一个DXERR的版本,您可以从源代码中构建它并在项目中使用,以消除对遗留DirectX SDK的依赖。有关详细信息,请参见this post。尽管如此,我故意只支持Unicode(W版本)。您可以找到如何轻松制作ANSI(A版本),但最好更新您的应用程序以使用Unicode。
请参见Where is the DirectX SDK (2021 Edition)?DXUT for Direct3D 11

更新:正如另一个答案中提到的那样,链接使用legacy_stdio_definitions.lib应该使旧版的DXERR库与VS 2015/2017重新链接。尽管如此,你应该尽可能地减少对旧版DirectX SDK的依赖,而且DXERR可以很容易地被自己的模块替换。请参见Living without D3DX


4
您使用的DirectX库是使用比您使用的Visual Studio旧版本编译的。微软有时会更改其C运行时,从而导致使用不同版本编译的库之间存在不兼容性。在早期版本的C运行时中,__vsnprintf是一个内部符号,在2015 RC版本中不存在。
不幸的是,dxerr.lib(以及d3dx11.lib)已被弃用。您有两个选择-可以切换回VS2013或停止使用dxerr.lib的功能。后者可能更好,因为现在可以使用FormatMessage来复制其功能(有关更多信息,请参见链接的文章)。

1
第三个选项是构建自己的 dxerr - Chuck Walbourn

3

虽然有些取巧,但你可以修补dxerr.lib。

用_vsnprintf替换__vsnprintf(在开头去掉下划线并在末尾添加null以进行调整)


2

您可以将平台工具集从Visual Studio 2015更改为Visual Studio 2013,然后进行编译。 平台工具集位于项目属性的常规选项卡中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接