Фатальная ошибка LNK1179: неверный или поврежденный файл: дублировать COMDAT '_IID_IXMLDOMImplementation'

Я получаю эту единственную ошибку, когда я связываю свой проект,

COMMUNICATION.obj: фатальная ошибка LNK1179: неверный или поврежденный файл: дублировать COMDAT '_IID_IXMLDOMImplementation'

Каков источник проблемы?

Ответ 1

Это сложный вопрос.

Проблема заключается в том, что символ (s) -генерированный слишком длинный, и существует двусмысленность:

  //...
  void MyVeryLongFunctionNameUnique_0(void);
  void MyVeryLongFunctionNameUnique_1(void);
  //   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  //   (example max-symbol-length-seen-by-linker)

В этом случае компоновщик "видит" эти две функции как "одинаковые", потому что часть, которая делает их "уникальными", длиннее длины символа-max.

Это может произойти, по крайней мере, в трех случаях:

  • Ваши имена символов слишком длинные, чтобы считаться уникальными для компоновщика, но, возможно, это было хорошо для компилятора (например, когда вы расширяете доступ к множеству вложенных шаблонов)
  • Вы сделали "обман", который является недопустимым С++, и он передал компилятор, но теперь у вас есть недопустимый *.obj, и он зажимает компоновщик.
  • Вы указали повторяющиеся "неназванные" классы/структуры, и компоновщик не может их разрешить.
  • === [UPDATE] ===. Это не ваша ошибка, это внутренняя проблема с компилятором и/или компоновщиком (см. ниже возможные возможности).

В зависимости от проблемы (выше) вы можете "увеличить" длину символа (путем ограничения длины вашего символа), или исправить свой код, чтобы сделать его действительным (недвусмысленным) С++.

Эта ошибка (минимально) описана Microsoft по адресу:

ПРИМЕЧАНИЕ.. Эта максимальная длина символа может быть установлена ​​с помощью опции /H, см. 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-С++ - code-that-compiles" (вы получаете свой *.obj), но этот недопустимый *.obj задерживает компоновщик (этот пример пытается использовать main как функция и как шаблон):

=== [ОБНОВЛЕНИЕ] ===

Я должен был сказать это раньше, потому что я подозревал, но теперь у меня есть дополнительная информация. Возможно, это не ваша ошибка. Кажется, что проблема в компиляторе и/или компоновщике вызывает эту ошибку. Это несмотря на то, что единственный общий знаменатель во всех ваших неудачных отношениях - это вы.

Напомним, что применяется "надпись" (он МОЖЕТ быть вашей ошибкой). Однако в случае, если "это не ваша вина", здесь текущий список (я уверен, что этот список НЕ завершен).

  • В вашем файле *.ilk (файл промежуточной ссылки) есть внутренняя ошибка/коррупция. Удалите его и перестройте.
  • У вас есть /INCREMENTAL включен для связи, но почему-то эта инкрементная привязка не работает для вашего проекта, поэтому вы должны отключить его и перестроить (Project-Properties=>Configuration Properties=>Linker=>General=>Enable Incremental Linking [установить в "Нет" (/INCREMENTAL:NO)]
  • Проблема с "Оптимизацией" для "Складной COMDAT" в вашем использовании. Вы можете "Удалить избыточные COMDAT", перейдя в Project Proerties=>Configuration Properties=>Linker=>Optimization=>Enable COMDAT Folding, установите "Удалить избыточные COMDAT (/OPT:ICF)

Вот интересная нить от парня, который иногда может ссылаться, а иногда и нет, комментируя в/из пары строк кода. Это не тот код, который является проблемой - он просто не может связать последовательно, и похоже, что компилятор и/или компоновщик имеют внутреннюю проблему в некотором неясном случае использования:

Другие наблюдения из нетривиального веб-поиска:

  • Эта проблема представляется не редкой.
  • он, по-видимому, связан с какой-либо формой template<> использует
  • другие, похоже, видят эту проблему с сборкой "Release", когда у нее не было этой проблемы с сборкой "Debug" (но она также часто встречается в сборке "Debug" ).
  • Если ссылка "не удалась" на одной машине, она может "преуспеть" на другой машине сборки (не уверен, почему "чистая сборка" не имеет никакого эффекта).
  • если вы комментируете в/из особо значимых строк кода и завершаете сборку, и продолжайте делать это, пока весь код не будет прокомментирован снова, ваша ссылка может преуспеть (это, кажется, повторяемо)
  • если вы получите эту ошибку с MSVC2008, и вы переносите свой код на MSVC2010, вы все равно получите эту ошибку.

=== [ПЕТИНА ДЛЯ ХОРОШИХ ЛЮДЕЙ МИРА] ===

Если у вас есть другие замечания по этой ошибке, перечислите их ниже (как другие ответы или комментарии ниже этого ответа). У меня есть аналогичная проблема, и это не моя вина, и ни один из этих work-arounds не работал у меня (хотя в некоторых случаях они работали для других в своих проектах).

Я добавляю щедрость, потому что это сводит меня с ума.

=== [ОБНОВЛЕНИЕ + 2] ===

(вздох), Здесь больше вещей, которые нужно попробовать (которые, видимо, работают для других, но не работают для меня):

  • этот парень изменил свои настройки компиляции, и он работал (из потока в http://forums.codeguru.com/showthread.php?249603.html):

    Project->Settings->C++ tab, Debug cathegory: Inline function expansion: измените значение с 'None' на 'Only _inline'.

  • приведенный выше поток ссылается на другой поток, где необходимо было повторно установить MSVC

  • возможно, связано с привязкой модулей с "тонкими различиями" в возможно-несовместимых компиляторах и/или переключателях ссылок. Убедитесь, что все "вкладки libs" построены с помощью тех же самых ключей

Вот еще несколько симптомов/наблюдений по этой ошибке/ошибке:

  • Список
  • для вышеуказанных проблем все еще применяется
  • проблема кажется "начальным показанием" с MSVC2005 и продолжается с тем же поведением для MSVC2008 и MSVC2010 (ошибка по-прежнему возникает после переноса кода на более новые компиляторы)
  • перезагрузка IDE, перезагрузка машины, похоже, не работает для кого-либо.
  • один парень сказал, что явная "чистая", за которой следует перекомпиляция, работала для него, но многие другие говорят, что это не сработало для них.
  • часто связан с "инкрементной привязкой" (например, отключите его).

Статус: без радости.

=== [UPDATE + 3: УСПЕХ ЛИНК] ===

Super-wacky-does-no-sense fix, чтобы успешно установить связь!

Это вариант (выше), в котором вы "играете" с скриптом-с-кодом-до-компилятора и/или-линкером ". НЕ ХОРОШО, что это может понадобиться.

Конкретная ошибка одиночного компоновщика (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 для каждой успешной ссылки на каждый после применения обхода).

ЭТО ОБРАТНАЯ СВЯЗЬ И/ИЛИ LINKER ERROR, так как код "simple/proper-С++" (даже С++ 11).

Итак, я счастлив (что у меня есть ссылка после того, как я перестал работать на 2 недели). Но, разочарованный (что компилятор и/или компоновщик имеют ПРОБЛЕМУ ПРОБЛЕМЫ STUPID с привязкой SIMPLE TEMPLATE < > в этом прецеденте, который я не мог понять, как обращаться).

ДАЛЕЕ, "Bounty Ended" , но никто больше не хотел этого делать (никаких других ответов?), поэтому выглядит " +100" никому не нравится, (Тяжелый вздох)

Ответ 2

На этот вопрос есть много ответов, но ни один из них не полностью отражает то, что происходило в моей кодовой базе, и то, что я подозреваю, ОП увидел в далеком 2012 году, когда был задан этот вопрос.

Эта проблема

Ошибка IID_* типа IID_* легко воспроизвести случайно, используя директиву #import с rename_namespace и named_guids.

Если два #import библиотеки типа изда содержит один и тот же интерфейс, как и, вероятно, в случае 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 диагностики duplicate COMDAT.

Решение

Зная, что rename_namespace не очень хорошо работает с named_guids, очевидным решением будет просто не использовать их вместе. Вероятно, проще всего удалить атрибут named_guids и вместо этого использовать оператор _uuidof().

После удаления named_guids из директив #import и named_guids кода, заменив все варианты использования FOO::IID_IFooBar на _uuidof(FOO::IFooBar), моя COM-насыщенная кодовая база снова возвращается к сборке.

Ответ 4

Я столкнулся с этой проблемой при переносе кода (1) из MSVC в GCC. Чтобы связать сборку с GCC, я должен был предоставить пустые реализации для некоторых специализированных шаблонных функций (2), и это привело к LNK1179 на MSVC. Я смог разрешить, вложив функции (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) {};

Ответ 5

Мне нужно было сделать С++ → генерация кода → enable link-level linking → no

Ответ 6

Надеемся, что мое хромое обходное решение поможет кому-то: я обязательно удалю все файлы .obj AND промежуточных файлов (включая, по крайней мере,.pch,.pdb,.tlog,.lastbuildstate и все остальное, просто висящее подозрительно) и перестроить с нуля.

Я предлагаю без доказательств, что наличие некоторых файлов, оставшихся после предыдущей сборки, приводит к тому, что проблема возникает чаще. В моей конкретной системе сборки я удаляю и воссоздаю файлы .vcxproj и .sln с нуля.

Мое личное подозрение в том, что в процессе сборки/ссылки существует какое-то состояние расы между временем, в течение которого промежуточные файлы читаются, и временем, которое они пишут в большом проекте. Опять же, у меня нет доказательств, что это правда, но это единственное мое предположение, которое, похоже, соответствует всем известным фактам ошибки.

Ответ 7

Я написал надстройки для Outlook несколько лет назад, и меня попросили написать еще одну. Я сразу же столкнулся с этой проблемой, и, пройдя небольшой процесс устранения, я исправил свою.

Оказывается, что когда вы выбираете проект на расширение (я вручную кодировал мой назад), он создает и сохраняет 2 объекта, о которых я не знал: DTE и DTE80. Для создания интерфейсов, управляющих этими объектами, они импортируются непосредственно из библиотек DLL в stdafx.h. Поскольку я работаю в Outlook, мне также нужно было импортировать несколько интерфейсов: Office и Outlook.

Итак, видя, как эта ошибка появилась почти сразу после написания моих первых кусочков кода, я начал все сначала и добавил по одной вещи за раз. Проект взорвал куски описанным способом сразу после того, как я добавил:

//Added mvc 
//The following #import imports MSO based on it 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 LIBID
#import "libid:00062FFF-0000-0000-C000-000000000046" rename_namespace("Outlook") raw_interfaces_only named_guids 
using namespace Outlook;

Итак, поскольку я не собирался выяснять материал DTE, я просто прокомментировал их и все, что с ними связано:

//The following #import imports VS Command Bars based on it 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 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 LIBID
//  #import "libid:1A31287A-4D7D-413e-8E32-3B374931BD89" version("8.0") lcid("0") raw_interfaces_only named_guids

После блуждания по исправлению ошибок компиляции он компилировался и связывался просто отлично. Я не предполагаю, что это будет работать для всех, но это сработало для меня. Удачи всем, кто проходит здесь....