2009-12-24 1 views
0

В каждой платформе есть различные версии данной библиотеки: многопоточный, отлаживать, динамический, и т.д ..Почему существует так много библиотек в MSVC и почему я должен перекомпилировать код снова

Поправьте меня если я ошибаюсь здесь, но в Linux объект может ссылаться на любую версию библиотеки просто отлично, независимо от того, как она скомпилирована. Например, нет необходимости использовать какие-либо специальные флаги во время компиляции, чтобы указать, будет ли ссылка в конечном итоге быть в динамической или статической версии библиотек времени выполнения (пояснение: я не говорю о , создавая динамический/статический библиотеки, я говорю об их привязке - так что -fPIC не применяется). То же самое касается отладочной или оптимизированной версии библиотек.

Почему в MSVC (Windows вообще с другими компиляторами? True?) Мне нужно перекомпилировать код каждый раз, чтобы ссылаться на разные версии библиотек? Я говорю флагов/MD,/MT,/MTd,/MDd и т. Д. Действительно ли код использует разные системные заголовки каждый раз. Если да, то почему?

Я бы очень признателен за любые указатели на твердую документацию, которая обсуждает эти вопросы библиотеки в Windows, для/C++ программиста C ..

спасибо!

+0

Linux требует связывания по имени библиотеки - MS предоставляет ключи/Mx в качестве удобства. – 2009-12-24 19:41:29

+0

Итак, это исключительно для удобства автоматического разрешения имен библиотек? – sly

ответ

4

Настройка компилятора очень мало, кроме простого изменения некоторых определений макросов. Его заголовочные файлы c-runtime от Microsoft, которые меняют свое поведение на основе выбранной среды выполнения.

Во-первых, файлы заголовков использовать директиву # ргадта встроить в объект файла директиву с уточнением .lib файл включить, выбрав одну из: MSVCRT.lib, MSVCRTD.lib, библиотеку libcmt.lib и mibcmtd.lib

директивы выглядеть следующим образом

#ifdef <release dll runtime> 
#pragma comment(lib,"msvcrt.lib") 
#endif 

Далее, он также изменяет определение макроса, используемое на все с-к.т. функций, добавляет __declspec(dllimport) директиву, если было выбрано длл выполнение. эффект этой директивы заключается в изменении импортированного символа, например, от '_strcmp' до '__imp__strcmp'.

Библиотеки импорта dll (msvcrt.lib и msvcrtd.lib) экспортируют свои символы (в компоновщик) как __imp_<function name>, что означает, что в мире Visual C++ после того, как вы скомпилировали код для связывания с временем выполнения dll, вы не могут изменить ваше мнение - они НЕ будут ссылаться на статическую среду выполнения. Конечно, обратное не так - библиотеки импорта dll фактически экспортируют свои общедоступные символы в обоих направлениях: с префиксом __imp_. Это означает, что код, созданный для статической среды выполнения, позже будет объединен со связью с dll или статическим временем автономной работы.

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

  1. Один из статических настроек библиотеки, так что потребители вашего .lib могут выбрать сами, которые c-runtime to use и
  2. Установите флаг «Omit Default Library Name» (/ Zl). Это говорит компилятору игнорировать директивы #pragma comment(lib,..., поэтому файлы obj и результирующая lib не имеют какой-либо неявной зависимости от времени выполнения. Если вы этого не сделаете, пользователи вашей библиотеки, которые выбирают другой параметр времени выполнения, будут видеть путаные сообщения о дублирующих символах в libc.lib и msvcrt.lib, которые им придется обойти, используя флаг игнорирования по умолчанию.
0

Все варианты используют одни и те же заголовочные файлы, однако все они подразумевают разные #define, которые влияют на файлы заголовков. Поэтому их нужно перекомпилировать.

Коммутаторы также ссылаются на соответствующую библиотеку, но перекомпилировать не из-за связи.

See here для определения того, что определено при использовании каждого.

+0

Да, правда. Но вы не ответили на мой вопрос: что это значит, что нужно менять вещи * во время компиляции *, чтобы ссылаться на другую версию библиотеки? Предположим, что на данный момент я хочу покончить с автоматической привязкой. Не могу ли я просто скомпилировать код и ссылку на любую доступную версию библиотеки? Или в другом случае, не могу ли я скомпилировать часть кода с debug, некоторые из них с флажками выпуска и свяжут их вместе? – sly

+0

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

1

Эти функции, использующие эти параметры компилятора, имеют два эффекта. Автоматически #define макрос, который может использоваться заголовками (и вашим собственным кодом), чтобы делать разные вещи. Это влияет только на небольшую часть времени выполнения C, и вы можете проверить заголовки, чтобы узнать, происходит ли это в вашем случае.

Другое дело, что компилятор C++ вставляет комментарий в ваш объектный файл, который сообщает компоновщику, что он автоматически включает особый вкус среды выполнения MSVC, независимо от того, укажите ли вы эту библиотеку во время ссылки или нет.

Это удобно для небольших программ, где вы просто вводите в командной строке cl myprogram.cpp для компиляции и ссылки, создавая файл myprogram.exe.

Вы можете победить автоматическое связывание комментируемого вкуса c-runtime, передав /nodefaultlib в компоновщик. Затем укажите другой вкус c-runtime. Это будет работать, если вы не будете зависеть от #defines для _MT и _DLL (имейте в виду, что стандартные заголовки C также могут смотреть на них).

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

Если вы хотите знать, какие части файлов заголовков C ведут себя по-разному, вы должны просто искать и _DLL в заголовках и видеть.

Смежные вопросы