VC8 до VC10 - ошибки LNK2005 - PullRequest
       28

VC8 до VC10 - ошибки LNK2005

11 голосов
/ 08 апреля 2011

Я недавно установил Visual Studio 2010 и использовал CMake для генерации файлов решения для моего проекта.Этот процесс ранее отлично работал на VS2005.

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

Моя текущая ситуация выглядит следующим образом: я компилирую DLL 1 , которая зависит только от некоторых системных библиотек (Kernel32 и т. Д.) и CRT и DLL 2 , которая ссылается на DLL 1 , а также некоторые сторонние библиотеки.

Я получаю следующие ошибки:

DLL1.lib(DLL1.dll) : error LNK2005: "public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::~basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(void)" (??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ) already defined in objFromDLL2.obj

Похоже, что это именно та проблема, которая описана здесь .

Однако ничто в этой теме не решает мою проблему.

  • Я подтвердил, что и DLL1, иDLL2 скомпилированы с флагом / MD Code Generation,
  • DLL2 ссылки на squish, glew и devil - я вручную перекомпилировал все эти и все библиотеки, от которых они зависят для VC10, такжес / MD
  • редактировать AВ соответствии с этой статьей (что похоже на мою проблему), я удалил все экземпляры классов, производных от std :: container
  • edit Я подтвердил, что этоне сторонняя проблема, так как я успешно скомпилировал другой проект с использованием того же набора библиотек, однако я все еще не могу скомпилировать свой оригинальный проект
  • edit dllexport используется во всех необходимых местах вмой код

Что мне не хватает?Пожалуйста, дайте мне знать, если мне потребуется предоставить больше информации, и я отредактирую вопрос, как смогу.

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

больше обновлений: Я обнаружил, что, вероятно, очень нежелательный флаг компоновщика, / FORCE: MULTIPLE, который превращает ошибки в предупреждения, игнорируя все, кроме первого определениясимволы.Там должно быть плохие побочные эффекты этого.Тест этого флага выделил LNK2001: unresolved std :: string :: npos, который был похоронен во всех предыдущих ошибках LNK2005.Мучение никогда не заканчивается.

Ответы [ 3 ]

2 голосов
/ 02 сентября 2011

Я успешно использовал /FORCE:MULTIPLE.Иногда это неизбежно при использовании смешанного пакета библиотек.Пока компоновщик использует один и тот же адрес для последовательного разрешения ссылки, он работает.Другие определения игнорируются.

0 голосов
/ 15 апреля 2011

Кажется, что проблема в том, что DLL1 действительно экспортирует std::string (возможно, неявно, потому что он используется в классе, который также экспортируется), но заголовки DLL1 не декларируют это. Поэтому, когда DLL2 скомпилирована, она не помечается как импорт. Это не проблема, потому что это шаблон: компилятор просто создает другую копию. Но тогда компоновщик спотыкается, потому что DLL2 действительно должен был импортировать std::string.

Решение: явный экспорт / импорт std::string; у вас, вероятно, уже есть соответствующий макрос для _declspec( ) в ваших заголовках DLL1.

0 голосов
/ 15 апреля 2011

Я склонен думать, что ваши высказанные предположения неверны.В частности, «DLL 1, которая зависит только от некоторых системных библиотек (Kernel32 и т. Д.)», Не может быть правильной, если она скомпилирована с / MD и ссылается на std::string::~string.Это, очевидно, вызвало бы зависимость от CRT.

Также, если DLL1 не зависит от DLL2, то как в мире линкер знает о файлах из DLL2 ?!Удалось ли вам случайно установить циклическую зависимость?

Между VS2008 и VS2010, похоже, что std::string::~string был удален из CRT.Следовательно, это больше не DLLimport для вашего собственного кода.Это может объяснить разницу в поведении.Циклическая зависимость между DLL1 и DLL2 не имела бы значения до std::string::~string, так как оба получали бы ее из CRT, и это, очевидно, не было бы частью цикла.

...