当我链接我的项目时,我收到了这个错误,
COMMUNICATION.obj:致命错误 LNK1179:文件无效或损坏:重复 COMDAT '_IID_IXMLDOMImplementation'
问题的根源是什么?
当我链接我的项目时,我收到了这个错误,
COMMUNICATION.obj:致命错误 LNK1179:文件无效或损坏:重复 COMDAT '_IID_IXMLDOMImplementation'
问题的根源是什么?
这是一个棘手的问题。
问题是生成的符号太长,并且存在歧义:
//...
void MyVeryLongFunctionNameUnique_0(void);
void MyVeryLongFunctionNameUnique_1(void);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// (example max-symbol-length-seen-by-linker)
在这种情况下,链接器将这两个函数“视为”“相同”,因为使它们“唯一”的部分比最大符号长度长。
至少在三种情况下会发生这种情况:
*.obj
,它阻塞了链接器。根据问题(以上),您可以“增加”符号长度(通过限制符号长度的减少),或修复代码以使其有效(明确)C++。
此错误(最低限度)由 Microsoft 在以下位置描述:
注意:此最大符号长度可以使用/H
选项设置,请参阅:http: //msdn.microsoft.com/en-us/library/bc2y4ddf (v=vs.90).aspx
/H
在您的命令行上使用 。如果是,则删除它(不指定max-symbol-length,默认为2,047
,/H
只能减少这个长度,不能增加它)。但是,您可能通过/Gy
选项(函数级链接)触发了它,这可能是通过 、 或 之一暗示的/Z7
:/Zi
http /ZI
: //msdn.microsoft.com/en-us/library/958x11bc(v=vs. 90).aspx
一个讨论此问题的 MSDN 线程是:
该线程表明可以使用“invalid-C++-code-that-c *.obj
ompiles”(你得到你的)触发这个问题,但是这会*.obj
导致链接器无效(这个例子试图main
同时用作函数和模板) :
===[更新]===
我之前应该这么说,因为我怀疑,但我现在有更多信息:这可能不是你的错,编译器和/或链接器中似乎存在触发此错误的问题。尽管事实上你所有失败的关系中唯一的共同点是你。
回想一下“上面的列表”适用(这可能是你的错)。但是,在“这不是你的错”的情况下,这里是当前运行列表(我相信这个列表不完整)。
*.ilk
您的文件(中间链接文件)中存在内部错误/损坏。删除它并重建。/INCREMENTAL
打开链接,但不知何故增量链接不适用于您的项目,因此您应该将其关闭并重建(Project-Properties=>Configuration Properties=>Linker=>General=>Enable Incremental Linking
[设置为“否”(/INCREMENTAL:NO
)]Project Proerties=>Configuration Properties=>Linker=>Optimization=>Enable COMDAT Folding
,设置为“删除冗余 COMDATs ( /OPT:ICF
)这是一个有趣的线程,他有时可以链接,有时不能,通过注释/注释几行代码。问题不是代码——他只是无法一致地链接,而且看起来编译器和/或链接器在一些晦涩的用例下存在内部问题:
来自非平凡网络搜索的其他观察结果:
template<>
使用有关===[给世界好人的请愿书]===
如果您对此错误有其他意见,请在下面列出(作为其他答案,或作为此答案下方的评论)。我有一个类似的问题,这不是我的错,而且这些变通方法都不适合我(尽管在某些情况下它们似乎确实适用于他们的项目中的其他人)。
我正在增加赏金,因为这让我发疯。
===[更新+2]===
(叹气),这里有更多要尝试的东西(显然对其他人有用,但对我不起作用):
这家伙改变了他的编译设置,它工作了(来自http://forums.codeguru.com/showthread.php?249603.html的线程):
Project->Settings->C++ tab, Debug cathegory: Inline function expansion
: 从 ' None
' 更改为 ' Only _inline
'。
上面的线程引用了另一个必须重新安装 MSVC 的线程
它可能与在可能不兼容的编译器和/或链接开关中链接具有“细微差异”的模块有关。检查所有“贡献库”是否使用完全相同的开关构建
以下是有关此错误/错误的更多症状/观察结果:
状态:不开心。
===[更新+3:链接成功]===
超级古怪的无意义修复成功发现链接!
这是(上图)的一个变体,您可以在其中“摆弄代码直到编译器和/或链接器行为”。不好的是可能需要这样做。
特定的单个链接器错误 ( LNK1179
) 用于MyMainBody<>()
:
#include "MyClassA.hpp"
#include "MyClassB.hpp"
#include "MyClassC.hpp"
#include "MyClassD.hpp"
#include "MyMainBody.hpp"
int main(int argc, char* argv[])
{
// Use a function template for the "main-body",
// implementation is "mostly-simple", instantiates
// some local "MyClass" instances, they reference
// each other, and do some initialization,
// (~50 lines of code)
//
// !!! LNK1179 for `MyMainBody<>()`, mangled name is ~236 chars
//
return MyMainBody<MyClassA,MyClassB,MyClassC,MyClassD>(argc,argv);
}
修复:
MyMainBody<>()
从 " template<>
"转换为显式函数 LINK SUCCESS。这个 FIX SUX,因为我需要 EXACT-SAME-CODE 用于其他实用程序中的其他类型,并且MyMainBody<>()
实现是非平凡的(但大多是简单的)实例化和设置,必须以特定的方式以特定的顺序完成.
但是,嘿,现在这是一个临时解决方法:在 MSVC2008 和 MSVC2010 编译器上确认(LNK1179
每个错误相同,在应用解决方法后每个都成功链接)。
这是编译器和/或链接器错误,因为代码是“简单/正确的 C++”(甚至不是 C++11)。
所以,我很高兴(我在全职工作 2 周后得到了一个链接)。但是,很失望(编译器和/或链接器有一个愚蠢的问题,在这个用例中链接一个简单的模板<>,我无法弄清楚如何解决)。
进一步,“赏金结束”,但没有其他人愿意接受这个(没有其他答案?),所以看起来“ +100 ”不给任何人。(沉重的叹息)
这个问题有很多答案,但没有一个能完全捕捉到我的代码库中发生的事情,以及我怀疑 OP 在 2012 年被问到这个问题时看到的内容。
使用带有和属性的指令IID_*
很容易意外重现类型上的 COMDAT 错误。#import
rename_namespace
named_guids
如果两个#import
ed 类型库包含相同的接口,就像 OP 的情况一样IXMLDOMImplementation
,那么生成的.tlh
文件将IID_IXMLDOMImplementation
在两个命名空间中声明,从而导致重复。
例如,生成的代码:
#import <foo.tlb> rename_namespace("FOO") named_guids;
#import <bar.tlb> rename_namespace("BAR") named_guids;
...可以简化成这样的:
namespace FOO {
extern "C" __declspec(selectany) const GUID IID_IFOOBAR = {0};
}
namespace BAR {
extern "C" __declspec(selectany) const GUID IID_IFOOBAR = {0};
}
这是问题的简单 RexTester 重现:https ://rextester.com/OLAC10112
该named_guids
属性导致IID_*
生成 并且该rename_namespace
属性将其包装在名称空间中。
不幸的是,在这种情况下,extern "C"
当它出现在 C++ 命名空间中时,它似乎没有按预期工作。IID_FOOBAR
这会导致编译器在同一个.obj
文件
中生成多个定义。DUMPBIN /SYMBOLS
或十六进制编辑器确认重复的符号。
链接器看到这些多个定义并发出duplicate COMDAT
诊断。
知道这rename_namespace
不能很好地与 一起使用named_guids
,显而易见的解决方案是根本不将它们一起使用。删除该named_guids
属性并改用_uuidof()
operator可能是最简单的。
在named_guids
从#import
指令中删除并修改代码,替换所有使用FOO::IID_IFooBar
with_uuidof(FOO::IFooBar)
之后,我的 COM 重代码库又重新开始构建了。
此问题在 Visual Studio 2017 的某些特定版本中报告为错误。尝试修补 15.9.1 或更高版本以修复此问题
我在将一些代码(1)从 MSVC 移植到 GCC 时遇到了这个问题。为了让构建链接到 GCC,我必须为一些专门的模板函数 (2) 提供空实现,这导致了 MSVC 上的 LNK1179。我能够通过内联函数(3)来解决,即
template<> template<> void LongName1<LongName2>::FunctionName(boost::library::type1 & a, const unsigned int b);
template<> template<> void LongName1<LongName2>::FunctionName(boost::library::type1 & a, const unsigned int b) {};
template<> template<> inline void LongName1<LongName2>::FunctionName(boost::library::type1 & a, const unsigned int b) {};
我收到了这个错误,对此感到非常困惑。结束注释掉引用的 cpp 中的所有内容并小批量重新引入内容,直到文件恢复到与我开始时相同的状态。而且我不再收到错误消息。对我来说,这在我的情况下表明这是编译器中的一个错误,但由于我无法再重现它,所以我无法获得更多帮助。
我在:Microsoft Visual Studio Professional 2019 版本 16.11.3
希望我蹩脚的解决方法可以帮助某人:我确保手动删除所有 .obj 和中间构建文件(至少包括 .pch、.pdb、.tlog、.lastbuildstate 和其他任何看起来可疑的东西)并从头开始重建。
我建议在没有证据的情况下,从以前的构建中遗留一些文件往往会导致问题更频繁地发生。在我的特定构建系统中,我也从头开始删除并重新创建 .vcxproj 和 .sln 文件。
我个人的怀疑是,在读取中间文件的时间和在大型项目中写入它们的时间之间,构建/链接过程中存在某种竞争条件。同样,我没有证据证明这是真的,但这是我唯一的猜测,似乎符合该错误的所有已知事实。
I wrote Outlook addins years ago and I was asked to write another. Right off the bat, I ran into this problem and through a little process of elimination, I fixed mine.
It turns out that when you choose an extensibity project(I hand coded mine back in the day), it creates and save 2 objects that I was unaware of: DTE and DTE80. To create the interfaces that manipulate these objects, they import directly from the DLLs in stdafx.h. Being that I'm working on Outlook, I also needed to import a couple of interfaces: Office and Outlook.
So, seeing as this error popped up almost immediately after writing my first tidbits of code, I started over, and added one thing at a time. The project blew chunks in the described way right after I added:
//Added mvc
//The following #import imports MSO based on it's LIBID
#import "libid:2DF8D04C-5BFA-101B-BDE5-00AA0044DE52" version("2.2") lcid("0") rename_namespace("Office") raw_interfaces_only named_guids
using namespace Office;
//The following #import imports Outoloks Object lib based on it's LIBID
#import "libid:00062FFF-0000-0000-C000-000000000046" rename_namespace("Outlook") raw_interfaces_only named_guids
using namespace Outlook;
So, seeing as I had no intention of figuring out the DTE stuff, I just commented out them and anything having to do with them:
//The following #import imports VS Command Bars based on it's LIBID
// #import "libid:1CBA492E-7263-47BB-87FE-639000619B15" version("8.0") lcid("0") raw_interfaces_only named_guids
//The following #import imports DTE based on it's LIBID
// #import "libid:80cc9f66-e7d8-4ddd-85b6-d9e6cd0e93e2" version("8.0") lcid("0") raw_interfaces_only named_guids
//The following #import imports DTE80 based on it's LIBID
// #import "libid:1A31287A-4D7D-413e-8E32-3B374931BD89" version("8.0") lcid("0") raw_interfaces_only named_guids
After wandering around fixing the compile errors, it compiled and linked just fine. I'm not suggesting this will work for everybody, but it worked for me. Good luck to any who pass by here....
我必须做 c++ -> 代码生成 -> 启用功能 - 级别链接 -> 否