Получение ошибки при компиляции режима отладки: C ++ / CLI - ошибка LNK2022 - PullRequest
3 голосов
/ 30 января 2011

У меня есть код CLI, обертывающий C ++ DLL.
Когда я пытаюсь скомпилировать его в режиме отладки, я получаю следующую ошибку:

Ошибка 22 Ошибка LNK2022: операция метаданныхошибка (8013118D):

Непоследовательная информация о макете, предполагаемые типы .... MSVCMRTD.lib (locale0_implib.obj)

Странная вещь в том, что в режиме Release он компилируется и работаетОК.
Единственное различие, которое я вижу, которое вызывает проблему, это когда я меняю:

Свойства конфигурации -> C / C ++ -> Генерация кода -> Библиотека времени выполнения

Когда установлено: Multi-threaded Debug DLL (/MDd) выдает ошибку.
Когда установлено: Multi-threaded DLL (/MD) хорошо компилируется.

Те же настройки работают для всех остальных библиотек DLL в проекте (CLI и C ++), и они наследуют одни и те же свойства.

Я использую VS2010.

Итак, как я могу решить эту проблему?

И могу ли я получить какое-то объяснениеПОЧЕМУ это происходит?

Обновление:

Я в основном пыталсябезуспешно меняя каждую опцию в свойствах проекта.

Я где-то читал, что это может быть вызвано дублирующими объявлениями типа с одинаковым именем.
Но в файле CLI я вызываюstd :: string и т. д. явно из std.

  • Переименование объектов не сработало

Есть другие идеи?

Обновление:

Несколько копий ошибок:

error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std._String_val<char,std::allocator<char> >): (0x02000097).  E:\MyProject....\MSVCMRTD.lib(locale0_implib.obj)   DllName


error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std._String_iterator<char,std::char_traits<char>,std::allocator<char> >): (0x02000091).  E:\MyProject....\MSVCMRTD.lib(locale0_implib.obj)   AnotherDllName

Обратите внимание, что файл MSVCMRTD.lib на самом деле является файлом MS, используемым для компиляции, и нена самом деле в моем проекте (и не должно быть)

Обновление

Если вам это помогает, вот командная строка компоновщика:

/ OUT: "E: \ blah.CLI.dll" / INCREMENTAL / NOLOGO / LIBPATH: "e: \ blah \ Output \" / LIBPATH: "E: \ blah \ lib_64" / LIBPATH: "blah \ Lib_64 \" / DLL "e: \ Otheblaf.lib "/ MANIFEST /ManifestFile:"x64\Debug\blah.CLI.dll.intermediate.manifest" / ALLOWISOLATION / MANIFESTUAC: "level =" asInvoker 'uiAccess =' ​​false '"/ DEBUG / PDB:"E: \ blah.CLI.pdb "/ SUBSYSTEM: WINDOWS / OPT: NOREF / OPT: NOICF /PGD:"E:\blah.CLI.pgd "/ TLBID: 1 / DYNAMICBASE: NO / FIXED: NO / MACHINE: X64 / ERRORREPORT: QUEUE

И выпуск, который работает:

/ OUT: "E: \ blah.CLI.dll" / ДОПОЛНИТЕЛЬНО: НЕТ / NOLOGO / LIBPATH: "E: \ blah \" / LIBPATH: "E: \ blah \ Output \" / LIBPATH: "E: \ blah \ lib_64" / DLL "Configuration.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib "" advapi32.lib "" shell32.lib "" ole32.lib "" oleaut32.lib "" uuid.lib "" odbc32.lib "" odbccp32.lib "" E: \ blah.lib "/ MANIFEST / ManifestFile: "blah.CLI.dll.intermediate.manifest" / ALLOWISOLATION / MANIFESTUAC: "level = 'asInvoker' uiAccess = 'false'" / DEBUG /PDB:"E:\blah.CLI.pdb "/ SUBSYSTEM: WINDOWS / OPT: REF / OPT: ICF /PGD:"E:\blah.CLI.pgd "/ LTCG / TLBID: 1 / DYNAMICBASE / FIXED: NO / MACHINE: X64 / ERRORREPORT: QUEUE

Ответы [ 6 ]

2 голосов
/ 09 марта 2011

Используете ли вы собственные make-файлы или настраиваемые параметры компилятора при сборке проектов? Это может повредить проекты невообразимым образом.

[a] Возможно, что параметр пакета прагмы при сборке этой DLL был задан как пользовательский параметр компилятора, что приводило к неправильной упаковке структур в стандартных заголовках Windows, что приводило к несоответствию размеров. Легко исправить .. проверьте настройки -Zp для cl.exe
Эта ситуация может решить случаи, когда структура является одной из ваших собственных пользовательских структур или классов.

http://msdn.microsoft.com/en-us/library/xh3e3fd0%28v=VS.71%29.aspx

[b] Другой случай, когда это может произойти, когда один из файлов заголовков включает заголовки Windows Standnd, а пакет Pragma не был восстановлен. Это затем распространяет неверную информацию о пакете на стандартные заголовки, вызывая те же проблемы, что и выше. Как правило, это легко решить, включив сначала все (более упрощенные) заголовки окон, чтобы потом их пропустить.

Надеюсь, это поможет.

1 голос
/ 12 апреля 2011

Наконец-то есть решение:

В конце концов, это была проблема в boost::lexical_cast<std:string>

Ошибка объекта .Net с использованием определенных std :: объектов,(в моем случае std :: string, как показано в сообщении об ошибке).

Это потому, что когда они создали эту платформу, они заново изобрели некоторые классы (std :: string является одним из них)но не сделал это должным образом в отладочной версии.
Подпись класса немного отличается.

Статья по теме MSDN - Неоднозначные ссылки

Итак,решение состоит в том, чтобы "скрыть" ошибочные классы от объекта .NET.

Создать класс-оболочку уровня C ++, который будет оборачивать функции исходного класса и преобразовывать типы ошибочных классов в другие типы классов, которые компилируются правильно.

Убедитесь, что в заголовке класса-обертки нет ссылок или включений на ошибочный тип класса.(Может быть сделано с осторожностью Прямая ссылка / decleration )
С VS2010 вы можете явно скомпилировать файл .cpp неуправляемой оболочки без / clr.

Затем вы можете правильно использовать класс-оболочку с управляемым классом ref.

Другой вариант

заменить lexical_cast<std::string> на:

ostringstream os;
os << i;
return os.str();
0 голосов
/ 01 декабря 2015

У меня была эта ошибка компоновки, когда я конвертировал свои проекты в 64 бит.Мое исправление было Свойства конфигурации > C / C ++ > Генерация кода > Выравнивание элементов структуры > 16 байт (/ Zp16)

0 голосов
/ 18 января 2012

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

0 голосов
/ 08 февраля 2011

Надеюсь, эта ссылка будет вам полезна.В этом MSDN предложено запустить 'ildasm –tokens' для объектных файлов, чтобы найти, для каких типов есть токены, перечисленные в error_message, и искать различия.

Здесь - некоторые входные данные для ildasmехе.

0 голосов
/ 06 февраля 2011

Обязательно очистите сборку перед компиляцией в режиме отладки.

...