Настройка компилятора мало что делает, кроме простого изменения некоторых определений макросов. Заголовочные файлы c-runtime его microsoft, которые изменяют свое поведение в зависимости от выбранной среды выполнения.
Во-первых, файлы заголовков используют директиву # pragma для встраивания в объектный файл директивы, определяющей, какой файл .lib следует включить, выбирая одно из: msvcrt.lib, msvcrtd.lib, libcmt.lib и mibcmtd.lib
Директивы выглядят так
#ifdef <release dll runtime>
#pragma comment(lib,"msvcrt.lib")
#endif
Затем он также изменяет определение макроса, используемое во всех функциях c-rt, которое добавляет директиву __declspec(dllimport)
, если была выбрана среда выполнения dll. эффект этой директивы - изменить импортированный символ, скажем, с '_strcmp'
на '__imp__strcmp'
.
Библиотеки импорта dll (msvcrt.lib и msvcrtd.lib) экспортируют свои символы (в компоновщик) как __imp_<function name>
, что означает, что в мире Visual C ++, после того как вы скомпилировали код для связи со средами выполнения dll Вы не можете передумать - они НЕ будут связываться со статической средой выполнения.
Конечно, это не так - библиотеки импорта dll на самом деле экспортируют свои публичные символы обоими способами: с префиксом __imp_
и без него.
Это означает, что код, созданный на основе статической среды выполнения, МОЖЕТ позднее быть связан с связью с DLL или статической средой выполнения.
Если вы создаете статическую библиотеку для других потребителей, вы должны убедиться, что в настройках вашего компилятора указаны:
- Одна из статических настроек библиотеки , чтобы пользователи вашего .lib могли сами выбирать, какое c-runtime использовать, и
- Установите флажок ' Пропустить имя библиотеки по умолчанию ' (/ Zl). Это говорит компилятору игнорировать директивы
#pragma comment(lib,...
, поэтому файлы obj и получающаяся библиотека не имеют какой-либо неявной зависимости во время выполнения. Если вы этого не сделаете, пользователи вашей библиотеки, выбравшие другой параметр времени выполнения, увидят непонятные сообщения о дубликатах символов в libc.lib и msvcrt.lib, которые им придется обойти, используя флаг игнорирования библиотек по умолчанию.