Разрешение LNK4098: defaultlib 'MSVCRT' конфликтует с

Это предупреждение:

LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts
  with use of other libs; use /NODEFAULTLIB:library

довольно общее предупреждение в Visual Studio. Я хотел бы понять точную причину его и правильный путь (если вообще) для обработки его.

Это подходит в отладочная сборка, скомпилированная с /MDd. Проект связан с вещами как окна Version.dll и pdh.dll которые самостоятельно связываются с MSVCRT.dll. Очевидно, я не имею отладочных версий их и не могу скомпилировать их.

Таким образом, я добавил /NODEFAULTLIB:MSVCRT к командной строке компоновщика и это на самом деле удаляло предупреждение. Но что это на самом деле делает? И почему это необходимо?

198
задан Edgar Rokjān 5 January 2018 в 03:14
поделиться

1 ответ

В vc\lib присутствуют 4 версии библиотек связей CRT:

  • libcmt.lib: статическая библиотека связей CRT для релизной сборки (/MT)
  • libcmtd.lib: статическая библиотека связей CRT для отладочной сборки (/MTd)
  • msvcrt. lib: библиотека импорта для релизной версии DLL CRT (/MD)
  • msvcrtd.lib: библиотека импорта для отладочной версии DLL CRT (/MDd)

Посмотрите на опции компоновщика, Project + Properties, Linker, Command Line. Обратите внимание, что эти библиотеки здесь не упомянуты. Компоновщик автоматически определяет, какой ключ /M был использован компилятором и какую .lib следует подключить через директиву #pragma comment. Это очень важно, так как при несоответствии между параметром /M и .lib, с которой вы компонуете, вы получите ужасные ошибки компоновки и трудно диагностируемые ошибки во время выполнения.

Вы увидите сообщение об ошибке, которое вы процитировали, когда компоновщику будет сказано одновременно скомпоновать msvcrt.lib и libcmt.lib. Это произойдет, если вы соедините код, скомпилированный с помощью /MT, с кодом, скомпилированным с помощью /MD. Может существовать только одна версия CRT.

/NODEFAULTLIB указывает компоновщику игнорировать директиву #pragma comment, которая была сгенерирована из скомпилированного кода /MT. Это может сработать, хотя нередко возникает множество других ошибок компоновщика. Например, errno, которая является extern int в статической версии CRT, но макросом для функции в версии DLL. И многое другое в том же духе.

Итак, чтобы решить эту проблему правильным способом, найдите .obj или .lib файл, который вы компонуете, который был скомпилирован с неправильной опцией /M. Если вы не знаете, то вы можете найти его, перебрав .obj/.lib файлы на предмет "/MT"

Btw: исполняемые файлы Windows (например, version.dll) имеют свою собственную версию CRT для выполнения своей работы. Она находится в c:\windows\system32, вы не можете надежно использовать ее для своих собственных программ, ее CRT-заголовки нигде не доступны. CRT DLL, используемая вашей программой, имеет другое имя (например, msvcrt90.dll).

254
ответ дан 23 November 2019 в 05:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: