Ami*_*hak 13 visual-studio-2005 visual-c++
当我链接项目时,我收到这个错误,
COMMUNICATION.obj:致命错误LNK1179:文件无效或损坏:重复COMDAT'_IID_IXMLDOMImplementation'
这个问题的根源是什么?
cha*_*ley 39
这是一个棘手的问题.
问题是生成的符号太长,存在歧义:
//...
void MyVeryLongFunctionNameUnique_0(void);
void MyVeryLongFunctionNameUnique_1(void);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// (example max-symbol-length-seen-by-linker)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,链接器"看到"这两个函数为"相同",因为使它们"唯一"的部分长于最大符号长度.
至少在三种情况下会发生这种情况:
*.obj,它会扼杀链接器.根据问题(上图),您可以"增加"符号长度(通过限制 - 减少符号长度),或修复代码以使其有效(明确)C++.
此错误(最低限度)由Microsoft描述:
注意:可以使用/H选项设置此max-symbol-length ,请参阅:http://msdn.microsoft.com/en-us/library/bc2y4ddf(v = vs.90).aspx
/H在命令行中使用了.如果是,删除它(不指定max-symbol-length,它将默认为2,047,/H只能递减此长度,不增加它).不过,你可能通过触发它/Gy的选项(功能级联),这很可能是通过一个暗示/Z7,/Zi或/ZI:http://msdn.microsoft.com/en-us/library/958x11bc(v=vs. 90)的.aspx
一个讨论此问题的MSDN线程是:
这个帖子暗示可以用"invalid-C++ - code-that- *.objcompiles "(你得到你的)来触发这个问题,但是这个无效 - 会*.obj阻塞链接器(这个例子试图main用作函数和模板) :
=== [UPDATE] ===
我之前应该说过,因为我怀疑,但我现在有更多信息:这可能不是你的错,编译器和/或链接器中似乎存在触发此错误的问题.尽管事实上你所有失败的关系中唯一的共同点就是你.
回想一下"上面列表"适用(可能是你的错).但是,在"这不是你的错"的情况下,这是当前运行列表(我确信这个列表不完整).
*.ilk(intermediate-link-file).删除它并重建./INCREMENTAL开启了链接,但不知何故增量链接对你的项目不起作用,所以你应该把它关掉并重建(Project-Properties=>Configuration Properties=>Linker=>General=>Enable Incremental Linking[设置为"No"(/INCREMENTAL:NO)]Project Proerties=>Configuration Properties=>Linker=>Optimization=>Enable COMDAT Folding设置为"删除冗余COMDAT"来删除冗余COMDAT(/OPT:ICF)这是一个有趣的线程来自一个有时可以链接,有时不通过注释/输出几行代码的人.这不是代码问题 - 他只是无法一致地链接,看起来编译器和/或链接器在一些不明确的用例下有一个内部问题:
来自非平凡网络搜索的其他观察:
template<>使用有关=== [对世界上好人的请求] ===
如果您对此错误有其他意见,请在下面列出(作为其他答案,或作为此答案下方的评论).我有一个类似的问题,这不是我的错,这些解决方案都没有为我工作(尽管在某些情况下它们确实似乎在他们的项目中为其他人工作).
我正在加入赏金,因为这让我疯了.
=== [UPDATE + 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);
}
Run Code Online (Sandbox Code Playgroud)
固定:
MyMainBody<>()从" template<>"一个明确的功能,连接成功.这个修复SUX,因为我需要其他实用程序中的其他类型的EXACT-SAME-CODE,并且MyMainBody<>()实现是非平凡的(但大多数是简单的)实例化和设置,必须以特定的方式按特定顺序完成.
但是,嘿,这是暂时的解决方法:在MSVC2008和MSVC2010编译器上确认(LNK1179每个都有相同的错误,在应用解决方法后每个成功链接).
这是编译器和/或链接器错误,因为代码是"简单/适当的C++"(甚至不是C++ 11).
所以,我很高兴(我在全职工作2个星期后获得了一个链接).但是,很失望(编译器和/或链接器有一个STUPID GLARING PROBLEM,在这个用例中链接了一个SIMPLE TEMPLATE <>,我无法弄清楚如何解决).
更进一步,"Bounty结束",但没有其他人想要接受这个(没有其他答案?),所以看起来像" +100 "没有人.(重叹气)
这个问题有很多答案,但没有一个能够完全反映我的代码库中发生的情况,以及我怀疑 OP 在 2012 年提出这个问题时看到的情况。
通过使用具有 和属性的指令IID_*,很容易意外地重现类型上的 COMDAT 错误。#importrename_namespacenamed_guids
如果两个#imported 类型库包含相同的接口,就像 OP 的情况一样IXMLDOMImplementation,那么生成的.tlh文件将在两个命名空间中声明IID_IXMLDOMImplementation,从而导致重复。
例如,生成的代码为:
#import <foo.tlb> rename_namespace("FOO") named_guids;
#import <bar.tlb> rename_namespace("BAR") named_guids;
Run Code Online (Sandbox Code Playgroud)
...可以简化为这样的:
namespace FOO {
extern "C" __declspec(selectany) const GUID IID_IFOOBAR = {0};
}
namespace BAR {
extern "C" __declspec(selectany) const GUID IID_IFOOBAR = {0};
}
Run Code Online (Sandbox Code Playgroud)
这是问题的简单 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()运算符可能是最简单的方法。
删除named_guidsfrom#import指令并修改代码,将所有使用替换为 后FOO::IID_IFooBar,_uuidof(FOO::IFooBar)我的 COM 密集型代码库又重新开始构建。