LNK 2022: несогласованная информация о компоновке после миграции на VS2010

У меня есть решение VS2010, которое содержит (среди прочего) следующие проекты:

  • Native.DLL (нативный проект C ++, который статически связан со сторонней библиотекой ITK, в которую входит STL)

Псевдокод (очень упрощенный):

using namespace std;

bool Native::CalcSomething(double* result, string& errorMsg);
  • Wrapper.DLL (проект C ++ / CLI, который динамически связывается с Native.DLL и использует std: string при вызове Native.DLL)

Псевдокод (очень упрощенный)

bool Wrapper::WrappedCalcSomething([System::Runtime::InteropServices::OutAttribute] double[] result,[System::Runtime::InteropServices::OutAttribute] System::String^ errorMsg)
{
Native* ntv = new Native();

std:string error;
pin_ptr<double> resultPtr = &result[0];

bool success = ntv->CalcSomething(resultPtr, error);

errorMsg = gcnew System::String(error.c_str());

return success;
}

Это скомпилировано и отлично скомпоновано в VS2008 (x64), но после миграции на VS2010 (по разным причинам) компоновщик выдает следующие ошибки:

2>  Generating Code...
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.logic_error): (0x02000049).
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.domain_error): (0x0200004a).
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.invalid_argument): (0x0200004b).
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.length_error): (0x0200004c).
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.out_of_range): (0x0200004d).
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.runtime_error): (0x0200004e).
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.overflow_error): (0x02000050).
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.underflow_error): (0x02000051).
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.range_error): (0x02000052).
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std._Locinfo): (0x02000054).
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (_Locimp): (0x02000059).
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (failure): (0x02000068).
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std._String_val<char,std::allocator<char> >): (0x02000097).
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std._String_val<wchar_t,std::allocator<wchar_t> >): (0x02000099).
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (lconv): (0x020000ce).
2>LINK : fatal error LNK1255: link failed because of metadata errors

Я прочитал почти все темы, которые я мог найти по этому вопросу, и попытался:

  • Очистить и восстановить
  • Переместить заголовки — нет ссылки на windows.h, и я попытался переместить строку #include безрезультатно
  • Использование флага / clr только для тех файлов, которые в нем нуждаются в Wrapper.DLL (это все файлы в проекте). Проблема заключается в том, что открытый метод в Native.DLL, который должен вызываться Wrapper.DLL, включает в свою подпись параметр std: string. Это затрудняет выделение ссылки на STL из области компиляции / clr
  • Я компилирую все (включая ITK, стороннюю библиотеку) с / MDd (и попробовал / MD) — изменение этого параметра, кажется, не влияет на вещи
  • я не вижу / Zp или прагма используется где угодно

Единственное «решение», о котором я могу подумать, — это изменить метод в Native.DLL, чтобы он не использовал std: string в качестве параметра (например, вместо этого используйте char *). Тем не менее, избегать использования STL в любых оболочках C ++ / CLI вряд ли кажется решением проблемы. Там должен будь лучше!

Примечание: мне известна статья о том, как «отладить» эти проблемы (ссылка на сайт), но если я не ошибаюсь, я думаю, что я знаю, что источником проблемы является std: string.

3

Решение

Я понял.

Я сделал синтаксическое изменение в одном из файлов CMake, который, по моему мнению, функционально идентичен тому, что происходило раньше (по сути, я использовал вспомогательную переменную CMake). Однако это, конечно, имело непредвиденные последствия, и полученные файлы проекта НЕ были одинаковыми.

В частности, проект Wrapper.DLL теперь связывался со сторонними библиотеками ITK, на которые вообще не нужно было ссылаться (это нужно только Native.DLL).

После возвращения CMake и правильной генерации проекта страшный LNK2022 ушел. Я только сам виноват за все эти потраченные часы …

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]