我收到此链接器错误。
mfcs80.lib(dllmodul.obj):错误 LNK2005:_DllMain@12 已在 MSVCRT.lib(dllmain.obj) 中定义
请告诉我消除此错误的正确方法。我在微软支持网站上阅读了关于这个错误的解决方案,但它并没有太大帮助。
我正在使用带有平台 SDK 的 VS 2005
我收到此链接器错误。
mfcs80.lib(dllmodul.obj):错误 LNK2005:_DllMain@12 已在 MSVCRT.lib(dllmain.obj) 中定义
请告诉我消除此错误的正确方法。我在微软支持网站上阅读了关于这个错误的解决方案,但它并没有太大帮助。
我正在使用带有平台 SDK 的 VS 2005
我有同样的错误信息,但这里的答案都没有为我解决。因此,如果您在创建使用 MFC 的 DLL 项目时遇到该问题,可以通过输入以下行来解决:
extern "C" { int _afxForceUSRDLL; }
到DllMain
定义的cpp文件。然后使用您自己的DllMain
实现,而不是来自 dllmain.obj 的实现。
当我们尝试使用 MFC 库时,肯定会直接或间接包含 afx.h,然后 MFC(afx.h) 告诉链接器找到 __afxForceUSRDLL 的符号并将包含 __afxForceUSRDLL 的对象放入程序中,因此链接器搜索并将 dllmodule.obj 放入我们的程序中,因为 __afxForceUSRDLL 是在 dllmodule.cpp 中定义的。
这是常见的情况。当我们想在mfc dll项目中使用自己的DllMain时,链接器抱怨有两个DllMain,一个在我们的代码中,一个在Dllmodule.obj中。
所以我们需要告诉链接器为 __afxForceUSRDLL 添加我们的 dllmain.obj。所以我们需要在我们自己定义了自己的DllMain的cpp文件中定义__afxForceUSRDLL,然后链接器会忽略mfc的dllmodule.obj,只看到一个DllMain,从不报错。
如果您彻底阅读链接器错误并应用一些知识,您可能会自己到达那里:
链接器将许多已编译的对象和库链接在一起以获取二进制文件。
每个对象/库描述
如果两个对象定义了相同的符号,你就会得到这个链接器错误。在您的情况下, mfcs80.lib 和 MSVCRT.lib 都定义了 _DllMain@12 符号。
摆脱错误:
如果您要定义自己的 DllMain,则需要在项目设置中将“配置属性/常规”中的“使用 MFC”设置为“使用标准 Windows 库”。
您应该在更改后进行干净的重建。
在我的项目中,我能够通过在项目设置中添加 mfcs80.lib 和 msvcrt.lib 作为附加依赖项来解决这个问题。“附加依赖项”可以在链接器 -> 输入下找到。
在调试配置中,必须分别是 mfcs80d.lib 和 msvcrtd.lib。
顺便说一句,我正在使用 Visual Studio 2010,所以在我的情况下,MFC 库称为 mfc100.lib。
我不确定为什么会这样。没有必要将这些 lib 文件添加为附加依赖项,因为我已经将“使用 MFC”设置为“在共享 dll 中使用 MFC”。我猜想通过将这些库指定为附加依赖项,它们以不同的顺序链接。
此解决方案与 Microsoft 网站上建议的解决方案大致相同:http: //support.microsoft.com/kb/148652,除了我不需要在“忽略特定默认库”框中键入任何内容。
对我来说,直接原因确实是缺少 _afxForceUSRDLL 符号引用,但间接原因是缺少 _USRDLL 宏定义。它由 VC 向导默认定义,但有时开发人员会错误地删除它。 这里有更多的话。
对于所有在 ATL 项目中遇到此错误的人(主要是在尝试添加 MFC 支持时),这是我经过几天的挫折后找到的解决方案!
首先,这个链接比其他链接对我更有帮助。它为我指明了正确的方向。如果“生成的文件”(包含代理和存根代码,就像类型 guid)由于某种原因已被删除并重新添加到项目中,则会出现问题。这会导致 Visual Studio 以错误的顺序添加它们!
通常您首先会遇到“ATL 需要 C++ 编译”错误,但您可能已经通过关闭该文件的Yc/Yu
(预编译头文件)设置来解决此问题。
您接下来应该做的是卸载您的项目并对其进行编辑。搜索定义构建并包含顺序(ClCompile
和ClInclude
)的项目组。检查他们的顺序和设置。
编译应按以下顺序出现:
dllmain.cpp
(CompileAsManaged
设置为false
并PrecompiledHeader
留空)。MyLib.cpp
,包含DllCanUnloadNow
等)MyLib_i.c
; 与 具有相同的设置dllmain.cpp
)stdafx.cpp
(PrecompiledHeader
设置为Create
)xdlldata.c
(与 相同的设置dllmain.cpp
)然后应该像这样订购包含的内容:
dllmain.h
MyLib_i.h
Resource.h
stdafx.h
targetver.h
xdlldata.h
修复构建顺序修复了我的项目,我能够创建一个新的干净构建。
MSDN 知识库 ID Q148652。
http://support.microsoft.com/kb/148652
原因:Visual C++ 按字母顺序编译源文件,并按字母顺序将编译的目标文件传递给链接器。如果链接器首先处理 DLLDATAX.OBJ,则源代码引用 DllMain,链接器从 MSVCRTD.LIB(dllmain.obj) 加载它。然后,链接器处理从包含#include "stdafx.h" 的 C++ 文件编译的目标文件,该文件引用符号 __afxForceUSRDLL,链接器从 MFC42D.LIB(dllmodul.obj) 加载该符号。此对象模块还包含 DllMain 的实现,从而导致冲突。
我有一个非常相似的问题。[mfcs110d.lib(dllmodul.obj) : error LNK2005: _DllMain@12 already defined in MSVCRTD.lib(dllmain.obj)] 解决方案是将 mfcs110d.lib 添加到 Additional Dependencies
就我而言,预处理器指令有问题。出于某种原因_USRDLL
,它不应该被定义。
要检查这一点,请转到 menu Project ,选择 Project Properties ,然后选择片段 Configuration Properties --> Preprocessor 。
预处理器指令将在那里找到。
就#undef
在_USRDLL
之前包括afx.h
,甚至更好的是,编辑您的项目配置并删除宏。
这是 MFC 扩展 DLL 的常用配置:MFC DLL的构建设置
确保在每个 .cpp 文件的顶部包含“Stdafx.h”。我遇到了完全相同的错误,并且有一个 .cpp 文件根本不包含此标头。添加#include 解决了这个问题。
我个人以这种方式摆脱了这个错误:右键单击项目中的Solution Explorer
,Properties
从弹出菜单中选择,单击Linker
选项卡并添加mfcs71ud.lib
到Additional Dependencies
. 如果您使用的是 Visual Studio 2005,它应该是“80”而不是“71”等等。
我在这里找到了解决方案 Visual Studio 2010 库链接顺序
这是: /FORCE:MULTIPLE 在链接器选项中
我必须将 ATL 和 MFC 混合在一起,才能使用 [module(name = "mymodule")]; MFC 应用程序中的构造以及“__hook”关键字
我发现这对我有帮助:http: //support.microsoft.com/kb/148652
基本上链接器顺序不正确。CRT 库在 MFC 库之前被链接。事实证明,必须首先链接 MFC 库,然后才能链接 CRT 库。
呸呸呸微软!!
在字段中声明mfc80ud.lib
and以解决问题。mfcs80ud.lib
Additional Dependancies
Project Properties -> Linker Tab -> Input of Visual Studio
这里的一些答案有一个共同的主题。
阿维舍克·玻色:-
在 Project Properties -> Linker Tab -> Input of Visual Studio 的 Additional Dependancies 字段中声明 mfc80ud.lib 和 mfcs80ud.lib 以解决此问题。
vmb100:-
我正在使用 Visual Studio 2010,因此在我的情况下,MFC 库称为 mfc100.lib。
何塞安德烈斯戈麦斯托瓦尔:-
我有一个非常相似的问题。[mfcs110d.lib(dllmodul.obj) : error LNK2005: _DllMain@12 already defined in MSVCRTD.lib(dllmain.obj)] 解决方案是将 mfcs110d.lib 添加到 Additional Dependencies
所以一般情况似乎是先找到要添加的库的名称...
然后添加它....
如果您的解决方案有多个导出相同符号的项目,也会发生这种情况。例如,如果您有foo.dll
一个foo.def
使用导出文件构建的子项目DoFoo
和bar.dll
一个使用bar.def
导出文件构建的子项目DoFoo
,则会发生冲突,这是您在链接时会看到的错误。