Я получаю эту единственную ошибку, когда я связываю свой проект,
COMMUNICATION.obj: фатальная ошибка LNK1179: неверный или поврежденный файл: дублировать COMDAT '_IID_IXMLDOMImplementation'
Каков источник проблемы?
Я получаю эту единственную ошибку, когда я связываю свой проект,
COMMUNICATION.obj: фатальная ошибка LNK1179: неверный или поврежденный файл: дублировать COMDAT '_IID_IXMLDOMImplementation'
Каков источник проблемы?
Это сложный вопрос.
Проблема заключается в том, что символ (s) -генерированный слишком длинный, и существует двусмысленность:
//...
void MyVeryLongFunctionNameUnique_0(void);
void MyVeryLongFunctionNameUnique_1(void);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// (example max-symbol-length-seen-by-linker)
В этом случае компоновщик "видит" эти две функции как "одинаковые", потому что часть, которая делает их "уникальными", длиннее длины символа-max.
Это может произойти, по крайней мере, в трех случаях:
*.obj
, и он зажимает компоновщик.В зависимости от проблемы (выше) вы можете "увеличить" длину символа (путем ограничения длины вашего символа), или исправить свой код, чтобы сделать его действительным (недвусмысленным) С++.
Эта ошибка (минимально) описана 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
)]Project Proerties=>Configuration Properties=>Linker=>Optimization=>Enable COMDAT Folding
, установите "Удалить избыточные COMDAT (/OPT:ICF
)Вот интересная нить от парня, который иногда может ссылаться, а иногда и нет, комментируя в/из пары строк кода. Это не тот код, который является проблемой - он просто не может связать последовательно, и похоже, что компилятор и/или компоновщик имеют внутреннюю проблему в некотором неясном случае использования:
Другие наблюдения из нетривиального веб-поиска:
template<>
использует=== [ПЕТИНА ДЛЯ ХОРОШИХ ЛЮДЕЙ МИРА] ===
Если у вас есть другие замечания по этой ошибке, перечислите их ниже (как другие ответы или комментарии ниже этого ответа). У меня есть аналогичная проблема, и это не моя вина, и ни один из этих 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" построены с помощью тех же самых ключей
Вот еще несколько симптомов/наблюдений по этой ошибке/ошибке:
Статус: без радости.
=== [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" никому не нравится, (Тяжелый вздох)
На этот вопрос есть много ответов, но ни один из них не полностью отражает то, что происходило в моей кодовой базе, и то, что я подозреваю, ОП увидел в далеком 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-насыщенная кодовая база снова возвращается к сборке.
Эта проблема сообщается как ошибка в некоторых конкретных версиях Visual Studio 2017. Попробуйте устранить неполадки 15.9.1 или более поздней версии, чтобы устранить эту проблему.
Я столкнулся с этой проблемой при переносе кода (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) {};
Мне нужно было сделать С++ → генерация кода → enable link-level linking → no
Надеемся, что мое хромое обходное решение поможет кому-то: я обязательно удалю все файлы .obj AND промежуточных файлов (включая, по крайней мере,.pch,.pdb,.tlog,.lastbuildstate и все остальное, просто висящее подозрительно) и перестроить с нуля.
Я предлагаю без доказательств, что наличие некоторых файлов, оставшихся после предыдущей сборки, приводит к тому, что проблема возникает чаще. В моей конкретной системе сборки я удаляю и воссоздаю файлы .vcxproj и .sln с нуля.
Мое личное подозрение в том, что в процессе сборки/ссылки существует какое-то состояние расы между временем, в течение которого промежуточные файлы читаются, и временем, которое они пишут в большом проекте. Опять же, у меня нет доказательств, что это правда, но это единственное мое предположение, которое, похоже, соответствует всем известным фактам ошибки.
Я написал надстройки для 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
После блуждания по исправлению ошибок компиляции он компилировался и связывался просто отлично. Я не предполагаю, что это будет работать для всех, но это сработало для меня. Удачи всем, кто проходит здесь....