プロジェクトをリンクしているときに、この単一のエラーが発生します。
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)
この場合、リンカはこれら 2 つの関数を「同じ」と「認識」します。これは、それらを「一意」にする部分が最大シンボル長よりも長いためです。
これは、少なくとも3 つのケースで発生する可能性があります。
*.obj
であり、リンカを詰まらせています。問題 (上記) に応じて、(シンボル長の減少を制限することによって) シンボル長を「増やす」か、コードを修正して有効な (明確な) C++ にすることができます。
このエラーは、Microsoft によって (最低限) 説明されています。
注:この max-symbol-length は/H
オプションで設定できます。次を参照してください: http://msdn.microsoft.com/en-us/library/bc2y4ddf(v=vs.90).aspx
/H
コマンドラインで が使用されている かどうかを確認してください。そうである場合は、削除します (max-symbol-length を指定しないでください。デフォルトで になります。2,047
は、この長さを減らす/H
ことしかできず、増やすことはできません)。ただし、オプション (function-level-linking) を介してトリガーした可能性があります。これは、、、またはのいずれか/Gy
によって暗示されている可能性があります。 90).aspx/Z7
/Zi
/ZI
この問題について話している 1 つの MSDN スレッドは次のとおりです。
このスレッドは、「invalid-C++-code-that-compiles」でこの問題を引き起こす可能性があることを示唆していますが (あなたはあなたの を取得します*.obj
)、invalid-*.obj
はリンカーをチョークします (この例main
では、関数とテンプレートの両方として使用しようとしています) 。 :
===[更新]===
疑っていたので、以前にこれを言うべきでしたが、より多くの情報が得られました。あなたのせいではないかもしれません。このエラーをトリガーするコンパイラやリンカーに問題があるようです。これは、失敗したすべての関係の唯一の共通点があなたであるという事実にもかかわらずです.
「上記のリスト」が適用されることを思い出してください(それはあなたのせいかもしれません)。ただし、「あなたのせいではない」場合は、現在実行中のリストを次に示します (このリストは完全ではないと確信しています)。
*.ilk
ファイル (intermediate-link-file)に内部エラー/破損があります。削除して再構築してください。/INCREMENTAL
オンにしましたが、何らかの形でそのインクリメンタル リンクがプロジェクトで機能しないため、オフにして再構築する必要があります ( Project-Properties=>Configuration Properties=>Linker=>General=>Enable Incremental Linking
[「いいえ」に設定 ( /INCREMENTAL:NO
)]Project Proerties=>Configuration Properties=>Linker=>Optimization=>Enable COMDAT Folding
( /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 を再インストールする必要があった別のスレッドを参照しています。
おそらく互換性のないコンパイラやリンクスイッチで「微妙な違い」を持つモジュールをリンクすることに関連している可能性があります。すべての「貢献ライブラリ」がまったく同じスイッチでビルドされていることを確認します
このエラー/バグに関するその他の症状/観察事項は次のとおりです。
ステータス: 喜びがない。
===[UPDATE+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 に変換します。THIS FIX SUX、他のユーティリティの他のタイプには EXACT-SAME-CODE が必要であり、MyMainBody<>()
実装は特定の方法で特定の順序で実行する必要がある、重要な (しかしほとんど単純な) インスタンス化とセットアップであるためです。 .
しかし、今のところ一時的な回避策です。MSVC2008 および MSVC2010 コンパイラで確認されています (回避策をLNK1179
適用した後、それぞれで同じエラーが発生し、リンクが成功しました)。
コードは「シンプル/適切な C++」(C++11 でさえない) であるため、これはコンパイラおよび/またはリンカーのエラーです。
だから、私は幸せです(フルタイムで2週間以上苦しんだ後、リンクを得たこと) . しかし、がっかりしました(コンパイラやリンカーには、このユースケースで SIMPLE TEMPLATE<> をリンクすることでSTUPID GLARING PROBLEMがあり、対処方法がわかりませんでした)。
さらに、「Bounty Ended」ですが、誰もこれを取りたがりませんでした(他に答えはありませんか?)ので、「+100」は誰にも行きません。(ため息)
この質問には多くの回答がありますが、私のコードベースで何が起こっていたのか、この質問が尋ねられたときに OP が 2012 年に見ていたと思われるものを完全に捉えているものはありません。
型の COMDAT エラーは、との両方の属性を持つディレクティブIID_*
を使用すると、誤って簡単に再現できます。#import
rename_namespace
named_guids
OP の場合のように、 2 つの#import
ed タイプ ライブラリに同じインターフェイスが含まれている場合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
または、16 進エディタが重複シンボルを確認します。
リンカーはこれらの複数の定義を確認し、duplicate COMDAT
診断を発行します。
rename_namespace
それが とうまく機能しないことを知っているnamed_guids
ので、明白な解決策は単純にそれらを一緒に使用しないことです。named_guids
属性を削除し、代わりに_uuidof()
operatorを使用するのがおそらく最も簡単です。
ディレクティブを削除named_guids
してコードを修正し、すべての使用をに置き換えた後、COM を多用するコードベースは再びビルドに戻りました。#import
FOO::IID_IFooBar
_uuidof(FOO::IFooBar)
私はc ++をしなければなりませんでした->コード生成->機能を有効にします-レベルリンク->いいえ
私の不十分な回避策が誰かを助けることを願っています.すべての.objおよび中間ビルドファイル(少なくとも.pch、.pdb、.tlog、.lastbuildstate、および疑わしいと思われるものをすべて含む)を手動で削除し、最初から再構築します。
以前のビルドからいくつかのファイルが残っていると、問題がより頻繁に発生する傾向があるという証拠はありません。私の特定のビルド システムでは、.vcxproj ファイルと .sln ファイルも最初から削除して再作成します。
私自身の個人的な疑念は、ビルド/リンク プロセスで、中間ファイルが読み取られてから大規模なプロジェクトに書き込まれるまでの間に、ある種の競合状態が存在することです。繰り返しますが、これが真実であるという証拠はありませんが、バグの既知の事実すべてに当てはまると思われる唯一の推測です。
MSVC から GCC にいくつかのコード (1) を移植しているときに、この問題が発生しました。ビルドを 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) {};