错误 LNK2005:在 LIBCMTD.lib(new.obj) 中已经定义了 new 和 delete。

45

我有一个Visual Studio 2005解决方案,其中有两个项目。一个是静态库,另一个是用于测试静态库功能的可执行文件。静态库使用MFC。当我构建解决方案时,出现了以下错误。

uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)" (??2@YAPAXI@Z) already defined in LIBCMTD.lib(new.obj)
uafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" (??    3@YAXPAX@Z) already defined in LIBCMTD.lib(dbgdel.obj)
uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new[](unsigned int)" (??_U@YAPAXI@Z) already defined in libcpmtd.lib(newaop.obj)
uafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete[](void *)" (??_V@YAXPAX@Z) already defined in LIBCMTD.lib(delete2.obj)

我不知道该如何克服这个问题。有人能解释一下为什么会出现这个错误吗?任何概述.lib文件链接的说明都将不胜感激。


另一个非静态库项目是否为 CRT 项目? - Donnie DeBoer
如果另一个(非静态库)项目是 CRT 项目,请查看此链接:http://support.microsoft.com/kb/148652。 - Donnie DeBoer
我在使用cl命令行编译控制台应用程序时遇到了这个错误。在我的库中使用了MFC的CString后,我才遇到这个问题。感谢KB文章,我只需将我的#include移到前面,问题就得到解决了。 - Synetech
18个回答

76
CRT 库使用新的,删除的和 DllMain 函数的弱外部链接。MFC 库也包含这些函数。这些函数要求在链接 CRT 库之前链接 MFC 库。 http://support.microsoft.com/kb/148652 基于 VS2005 的解决方案(对于 VS2013,请将 Nafxcwd.lib 替换为 Uafxcwd.lib):
转到项目>属性>配置属性>链接器>输入
添加到“附加依赖项” -> Nafxcwd.lib Libcmtd.lib
添加到“忽略特定库” -> Nafxcwd.lib;Libcmtd.lib
库的顺序很重要(Nafxcwd.lib;Libcmtd.lib)。

25
如果您正在使用Unicode编译,建议使用uafxcwd.lib而非nafxcwd.lib。需要注意的是,d只用于调试版本。在发布配置中,请使用uafxcw.lib和libcmt.lib。 - grim
1
我按照建议将它们放在附加依赖项中(在我拥有的任何其他内容之前),但不需要将它们放在“忽略特定库”中。对于那些寻找答案的人,这是“如何解决依赖性问题”的方法,正如此知识库文章第2步经常链接到此类问题。 - darda

17

有一件事可以尝试,就是确保你拥有:

#include "stdafx.h"

在你的 .cpp 文件中作为第一行。我相信这不是所有情况的答案,但在我的情况下,它消除了相同的错误。


1
我不知道自己是不是疯了,但在其他选项都无法解决问题后,我尝试了你的答案。错误消失了。然后我删除了一行以记录错误的确切性质……结果它们没有再出现?!嗯,C++编译器错误可以说是非常神秘了…… - mallardz
我独立得出了相同的结论。 - Mark Ch
是的,这对我也起作用了。我怀疑这是由于stdafx.h包含的内容所致。我想知道是否从所有文件中删除stdafx.h包含并删除stdafx.cpp会产生相同的效果? - Den-Jason

16

在 Visual Studio 2010 的 MFC 解决方案中,将 Use MFC in a Shared DLL 改为 Use MFC in a Static Library 时,我遇到了这个问题。我通过以下方式解决此问题,请先转到 Project -> Properties -> Configuration Properties -> Linker -> Input

在调试模式下:

  • Additional Dependencies中添加 uafxcwd.lib;Libcmtd.lib
  • Ignore Specific Default Libraries中添加 uafxcwd.lib;Libcmtd.lib

在发布模式下:

  • Additional Dependencies中添加 uafxcw.lib;Libcmt.lib
  • Ignore Specific Default Libraries中添加 uafxcw.lib;Libcmt.lib

注意事项:

  1. 不要漏掉两个 .lib 文件之间的 ;
  2. 在调试模式下,需要在文件名后面添加后缀 -d

7

请确保在其他包含文件之前,将#include <afx.h>包含在"stdafx.h"中,例如#include <string>


5

在配置链接器输入中

  • 在附加依赖项中添加uafxcw.lib;LIBCMT.lib
  • 在忽略特定项中添加uafxcw.lib;LIBCMT.lib

3

请确保您链接的C++运行时库在静态库和可执行文件中是相同的。检查您的项目属性 C/C++ -> 代码生成 -> 运行时库设置。


2

笔误。其中一个愚蠢的错误是,你包含了cpp文件而不是头文件。 例如:

#include <myclass.cpp> //should be #include <myClass.h>

正确。这在我的情况下发生了。我将所有的函数和类定义都放在了cpp文件中,然后出现了这个错误。当我将定义转移到hpp文件中时,错误消失了。奇怪! - Nav

1

我使用VS2017创建了两个新项目,其中一个可以工作,另一个不行,所以我比较了一下它们之间的区别。可以工作的那一个是通过以下步骤创建的:
文件 > 新建项目 > Visual C++ > MFC/ATL > MFC应用程序
而不能工作的那一个是通过以下步骤创建的:
文件 > 新建项目 > Visual C++ > Windows桌面 > Windows桌面向导
然后添加MFC。在这两种情况下,我都使用静态库作为MFC。我已经找到了两个解决方法。但在此之前,我们需要添加导入项,因为第二个项目没有任何导入项!

#include <afxwin.h>         // MFC core and standard components
#include <afxext.h>         // MFC extensions
#include <afxdisp.h>        // MFC Automation classes

现在,这两种方法都对我起作用了:

  1. 项目 > 属性 > 配置属性 > 常规 > MFC 的使用 设置为使用共享 DLL,这也应该自动设置 C/C++ > 代码生成 > 运行库多线程调试 DLL /MDd,确保它确实这样做了。尝试编译现在,对我来说有效。
  2. 我注意到工作中的项目在 stdafx.h 中有一些导入,我将它们复制到另一个项目的 pch.h 中,它就工作了(保持属性不变,因此使用了静态 lib)。复制的代码是这样的:
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // some CString constructors will be explicit

// turns off MFC's hiding of some common and often safely ignored warning messages
#define _AFX_ALL_WARNINGS
#include <afxwin.h>         // MFC core and standard components
#include <afxext.h>         // MFC extensions


#include <afxdisp.h>        // MFC Automation classes

我尝试了其他改变链接器设置的解决方案,但它们都没有起作用。 如果有人知道为什么我的解决方案有效,那我会很感激。这很奇怪,为什么在pch.h中包含这些头文件可以解决链接器问题,而在任何其他地方包含这些相同的头文件都会触发错误?

pch.h文件是作为预编译头文件生成的。您可以通过属性-> C/C++ -> 预编译头来关闭项目中的预编译头文件,并选择“不使用预编译头”。您还可以通过在解决方案资源管理器中右键单击文件并浏览属性菜单来为单个C/C++文件禁用预编译头。 - Den-Jason

1

解决了问题

uafxcwd.lib(afxmem.obj) : warning LNK4006: "void * __cdecl operator new(unsigned __int64)"
  • 在附加依赖项中添加uafxcw.lib
  • 在忽略特定项中放置uafxcw.lib

1

首先,libcmtd.lib是用于调试版本的,而libcmt.lib是用于生产环境的。请仔细检查您是否同时包含了两者。一个检查的地方是在“配置属性/链接器项目属性”的“命令行”部分。

如果您进入项目属性并打开“配置属性/链接器/输入”部分,您可以在“忽略特定库”中列出libcmtd.lib。


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