Подтвердить что ты не робот

Почему библиотека времени выполнения является компилятором, а не вариантом компоновщика?

Я пытаюсь создать статическую библиотеку C/С++ с использованием visual studio 2005. Поскольку выбор библиотеки времени выполнения является компиляцией, мне приходится создавать четыре варианта моей библиотеки, по одному для каждого варианта времени выполнения библиотека:

  • /MT - статическая библиотека времени выполнения
  • /MD - библиотека времени выполнения DLL
  • /MTd - отладка статической библиотеки времени выполнения
  • /MDd - отладка библиотеки времени выполнения DLL

Это параметры компилятора, а не параметры компоновщика. Исходя из фона Linux, это кажется странным. У разных библиотек времени исполнения разные соглашения о вызовах или что-то еще? Почему не удается разрешить разные библиотеки времени выполнения во время соединения, т.е. Когда я свяжу приложение, использующее мою статическую библиотеку?

4b9b3361

Ответ 1

Один побочный эффект определений препроцессора C, таких как _DLL и _DEBUG, о которых упоминалось zdan:

Некоторые структуры данных (например, контейнеры STL и итераторы) могут иметь разный размер во время выполнения отладки, возможно, из-за таких функций, как _HAS_ITERATOR_DEBUGGING и _SECURE_SCL. Вы должны скомпилировать свой код с определениями структуры, которые совместимы с бинарной библиотекой, с которой вы ссылаетесь.

Если вы смешиваете и сопоставляете файлы объектов, которые были скомпилированы для разных библиотек времени исполнения, вы получите предупреждения о компоновщике, например следующее:

warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs

Ответ 2

Эти параметры могут добавлять определения (например, __DLL и __DEBUG), которые используются в файлах заголовков библиотеки времени выполнения. Одной из распространенных вещей является добавление __declspec (dllimport) к объявлениям функций при динамическом соединении.

Компилятор также, по-видимому, использует их, чтобы помочь компоновщику связываться с правильными библиотеками. Это объясняется в MSDN.

Ответ 3

Компилятор должен знать, генерируете ли вы однопоточный или многопоточный код. По умолчанию компилятор генерирует безопасный для потока код (многопоточный). Вы должны сказать это, если вам нужен один поток кода. Если вы измените значение по умолчанию, компилятор изменит библиотеку времени выполнения по умолчанию (вы всегда можете переопределить это в параметрах командной строки компоновщика, просто убедитесь, что выбранная библиотека имеет тот же код структура как ваши объектные файлы: однопоточная статическая многопоточная статическая или многопоточная DLL). Обратите внимание, что нет однопоточной DLL-опции (по определению библиотека DLL во время выполнения будет построена как потокобезопасная, поскольку она разделяется несколькими приложениями).

Ответ 4

Если вы игнорируете статическое время выполнения, вы получаете те же параметры, что и Linux.

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

Наличие версии Release/Debug совпадает с версией Linux/Unix.
Хотя для эффективности я прихожу к тому, что я alos строю один поток и несколько потоков версий библиотек.

Ответ 5

Я считаю, что причиной этого является то, что код SEH (структурированный обработчик исключений) будет генерироваться по-разному в зависимости от того, с какой библиотекой среды выполнения вы ссылаетесь.

Ответ 6

Для DLL и статических библиотек существует другой машинный код.

И в Linux вы должны сделать то же самое, флаг компилятора называется -fPIC, если вы хотите создать общую библиотеку. В противном случае на AMD64 и SPARC (и, возможно, на других) он сработает. В архитектуре i386 компоновщик достаточно умен и не делит библиотеку в памяти, чтобы она не разбивалась.