问题描述
此警告:
LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts
with use of other libs; use /NODEFAULTLIB:library
是Visual Studio中相当普遍的警告.我想了解它的确切原因以及处理它的正确方法(如果有的话).
is a fairly common warning in Visual Studio. I'd like to understand the exact reason for it and the right way (if at all) to handle it.
这出现在使用/MDd
编译的调试版本中.该项目链接到诸如Windows Version.dll
和pdh.dll
之类的东西,它们本身与MSVCRT.dll
链接.显然,我没有这些的调试版本,也无法编译它们.
This comes up in a debug build, compiled with /MDd
. The project is linked to things like windows Version.dll
and pdh.dll
which themselves link with MSVCRT.dll
. Obviously, I don't have the debug versions of these and can't compile them.
因此,我在链接器命令行中添加了/NODEFAULTLIB:MSVCRT
,它确实删除了警告.但是,这实际上是做什么的呢?为什么有必要?
So I added /NODEFAULTLIB:MSVCRT
to the linker command line and it actually did remove the warning. But what does this actually do? And why is it necessary?
推荐答案
在vc \ lib中存在4种版本的CRT链接库:
There are 4 versions of the CRT link libraries present in vc\lib:
- libcmt.lib:发布版本(/MT)的静态CRT链接库
- libcmtd.lib:用于调试版本(/MTd)的静态CRT链接库
- msvcrt.lib:CRT(/MD)的发行DLL版本的导入库
- msvcrtd.lib:CRT(/MDd)的调试DLL版本的导入库
查看链接器选项:项目+属性",链接器",命令行".请注意,此处未提及这些库.链接器自动找出编译器使用了哪个/M开关,以及应该通过#pragma注释指令链接哪个.lib.有点重要,如果/M选项和您链接的.lib之间不匹配,则会出现可怕的链接错误,并且难以诊断运行时错误.
Look at the linker options, Project + Properties, Linker, Command Line. Note how these libraries are not mentioned here. The linker automatically figures out what /M switch was used by the compiler and which .lib should be linked through a #pragma comment directive. Kinda important, you'd get horrible link errors and hard to diagnose runtime errors if there was a mismatch between the /M option and the .lib you link with.
当链接器被告知同时链接到msvcrt.lib 和 libcmt.lib时,您将看到引用的错误消息.如果将用/MT编译的代码与用/MD链接的代码相链接,则会发生这种情况. CRT只能有一个版本.
You'll see the error message you quoted when the linker is told both to link to msvcrt.lib and libcmt.lib. Which will happen if you link code that was compiled with /MT with code that was linked with /MD. There can be only one version of the CRT.
/NODEFAULTLIB告诉链接器忽略从/MT编译代码生成的#pragma注释指令.尽管有很多其他链接器错误并不少见,但这可能会起作用.像 errno 这样的东西,在静态CRT版本中是extern int,但是在DLL版本中被宏化为一个函数.许多其他人都这样.
/NODEFAULTLIB tells the linker to ignore the #pragma comment directive that was generated from the /MT compiled code. This might work, although a slew of other linker errors is not uncommon. Things like errno, which is a extern int in the static CRT version but macro-ed to a function in the DLL version. Many others like that.
好吧,以正确的方式解决此问题,找到要链接的.obj或.lib文件,该文件是使用错误的/M选项编译的.如果您不知道任何线索,则可以通过将.obj/.lib文件复制为"/MT"来找到它
Well, fix this problem the Right Way, find the .obj or .lib file that you are linking that was compiled with the wrong /M option. If you have no clue then you could find it by grepping the .obj/.lib files for "/MT"
顺便说一句:Windows可执行文件(如version.dll)具有自己的CRT版本以完成其工作.它位于c:\ windows \ system32中,您不能可靠地将其用于自己的程序,它的CRT标头在任何地方都不可用.程序使用的CRT DLL具有不同的名称(如msvcrt90.dll).
Btw: the Windows executables (like version.dll) have their own CRT version to get their job done. It is located in c:\windows\system32, you cannot reliably use it for your own programs, its CRT headers are not available anywhere. The CRT DLL used by your program has a different name (like msvcrt90.dll).
这篇关于解决LNK4098:defaultlib'MSVCRT'与发生冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!