未解决的外部符号__imp__fprintf和__imp____iob_func,SDL2

128

有人可以解释一下什么是

__imp__fprintf

__imp____iob_func

未解决的外部引用错误吗?

因为当我尝试编译时会出现这些错误:

1>SDL2main.lib(SDL_windows_main.obj) : error LNK2019: unresolved external symbol __imp__fprintf referenced in function _ShowError
1>SDL2main.lib(SDL_windows_main.obj) : error LNK2019: unresolved external symbol __imp____iob_func referenced in function _ShowError
1>E:\Documents\Visual Studio 2015\Projects\SDL2_Test\Debug\SDL2_Test.exe : fatal error LNK1120: 2 unresolved externals

我可以肯定地说问题不在链接错误上。我已经正确地链接了一切,但出于某种原因它无法编译。

我正在尝试使用SDL2。

我正在使用Visual Studio 2015作为编译器。

我已经在链接器->输入->附加依赖项中链接了SDL2.lib和SDL2main.lib,并且我确保VC++目录是正确的。


1
请问您能否通过展示您的链接器设置来证明这一点? - πάντα ῥεῖ
@πάνταῥεῖ,我已经在输入链接器设置中链接了SDL2.lib和SDL2main.lib,并确保目录指向正确的位置。 - RockFrenzy
1
可能是error LNK2001 __imp_fprintf Visual Studio 2015 RC的重复问题。 - dewaffled
20个回答

2

2

这里有一个关于此解决方案的讨论:https://social.msdn.microsoft.com/Forums/vstudio/en-US/4a1c9610-fa41-45f6-ad39-c9f6795be6f2/msvcrt-iob-disappeared?forum=vclanguage - Sisir

0
在我的情况下,这个错误是由于我试图删除依赖于 MSVC 版本相关运行时库 DLL(如 msvcr10.dll)和/或删除静态运行时库以从我的可执行文件中删除多余的代码所导致的。
因此,我使用 /NODEFAULTLIB 链接器开关,自制的 "msvcrt-light.lib"(需要时请搜索谷歌),以及 mainCRTStartup() / WinMainCRTStartup() 入口点。
我认为这是自 Visual Studio 2015 以来的做法,所以我一直坚持使用旧版本编译器。
然而,定义符号 _NO_CRT_STDIO_INLINE 可以消除所有麻烦,一个简单的 "Hello World" 应用程序再次变得小巧精悍,只有 3 KB,并且不依赖于不寻常的 DLL。在 Visual Studio 2017 中测试通过。

0

我在尝试将 .lib 链接到我的 vs2015 项目时遇到了同样的问题(未解决的外部符号 __impl_printf)

唯一对我有效的解决方案是: 项目 -> 属性 -> 链接器 -> 命令行,在附加选项框中添加:legacy_stdio_definitions.lib


0

你是否遇到了与 OP 相同的错误,或者是“未解决的外部符号”? - HolyBlackCat
一般情况下是未解决的外部符号。直到我添加了shell32.lib才起作用。我没有意识到这个线程已经五年了...糟糕。 - Aeryes
1
通常来说,顶起旧帖是可以的,但链接 Shell32.lib 可能无法解决 OP 描述的问题(关键在于哪个符号“未解析”)。 - HolyBlackCat

0
为了在这个已经很丰富的线程中增加更多的混乱,我碰巧遇到了与fprintf相关的同样未解决的外部问题。
main.obj : error LNK2019: unresolved external symbol __imp__fprintf referenced in function _GenerateInfoFile

即使在我的情况下,它是在一个相当不同的上下文中出现的:在Visual Studio 2005(Visual Studio 8.0)下,错误发生在我的自己的代码中(我正在编译的完全相同的代码),而不是第三方代码。

事实证明,这个错误是由我的编译器标志中的/MD选项触发的。切换到/MT可以解决这个问题。这很奇怪,因为通常静态链接(MT)比动态链接(MD)更容易引起问题...但以防万一,我把它放在那里。


0
这种情况可能发生在您链接到 msvcrt.dll 而不是 msvcr10.dll(或类似文件)时,这是一个好的解决方案。因为它将使您能够在最终软件包中重新分发 Visual Studio 的运行时库。
这个解决方法对我很有帮助(在 Visual Studio 2008 中)。
#if _MSC_VER >= 1400
#undef stdin
#undef stdout
#undef stderr
extern "C" _CRTIMP extern FILE _iob[];
#define stdin   _iob
#define stdout  (_iob+1)
#define stderr  (_iob+2)
#endif

这段代码对于Visual Studio 6及其编译器是不需要的。因此使用#ifdef。


0

这适用于Visual-Studio 2017:

#include<corecrt_wstdio.h>
FILE* __cdecl __iob_func(unsigned const id)
{
   return(__acrt_iob_func(id));
}

-1

我成功解决了这个问题。

错误的源头是在 SDLmain 源代码中可以找到的这行代码。

fprintf(stderr, "%s: %s\n", title, message);

所以我所做的就是编辑SDLmain中该行的源代码:

fprintf("%s: %s\n", title, message);

然后我构建了SDLmain并将旧的SDLmain.lib复制并替换为新构建和编辑的文件,放在我的SDL2库目录中。

然后当我使用SDL2运行程序时,没有出现任何错误消息,代码运行顺畅。

我不知道这是否会在以后给我带来麻烦,但目前一切都很顺利。


1
你所做的更改本身就是一个错误,并不能解决你在问题描述中提到的问题。你不再收到链接器错误只是巧合,可能仅仅是因为你重建了库的方式导致的。 - Ross Ridge
@RossRidge,噢,是的,可能就是那样。啊,好吧。 - RockFrenzy

-3

将此代码粘贴到任何源文件中并重新构建。 对我有用!

 #include <stdio.h>

FILE _iob[3];

FILE* __cdecl __iob_func(void)
{

   _iob[0] = *stdin;

   _iob[0] = *stdout;

   _iob[0] = *stderr;

   return _iob;

}

你应该使用 ``` 添加格式,并添加一些解释。 - Antonin GAVREL
虽然这段代码可能解决了问题,但是包括解释它如何以及为什么解决了问题,将有助于提高您的帖子质量,并可能导致更多的赞。请记住,您正在回答未来读者的问题,而不仅仅是现在提问的人。请[编辑]您的答案以添加解释并指出适用的限制和假设。 - Brian61354270

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