код смешивания, скомпилированный с /MT и / MD

у меня есть большой объем кода, скомпилированный с /MT (т. е. ожидающий статической связи с CRT). Мне нужно объединить это со статической сторонней библиотекой, которая была построена с /MD (т. е. ожидая динамической связи CRT).

теоретически возможно ли связать их в один исполняемый файл без перекомпиляции?

Если я свяжусь с /nodefaultlib: msvcrt, я получу небольшое количество неопределенных ссылок на такие вещи, как __imp__wgetenv. Я соблазн попробовать реализовать эти функции в моем собственном коде, перенаправляя в wgetenv, etc. Стоит ли пытаться, или я сразу же столкнусь со следующей проблемой?

к сожалению, мне запрещено принимать простой вариант упаковки кода thirdparty в отдельную DLL: -/

3 ответов


нет. / MT и / MD являются взаимоисключающими.

все модули, переданные данному вызову компоновщика, должны быть скомпилированы с тем же параметром компилятора библиотеки времени выполнения ( / MD, / MT, /Л. Д.).

источник


Я нашел такое решение в источниках OpenSSL: все obj-файлы библиотеки скомпилированы с комбинацией:/MT /Zl. Как описал автор, такая комбинация позволяет построить статическую библиотеку с возможностью компиляции с приложениями либо динамической CRT (/MD) или статической CRT (/MT).


Я столкнулся с аналогичной ситуацией, когда у меня было две библиотеки, одна была построена с MT, а другая с MD. Мне пришлось создать исполняемый файл, который использует функции из библиотеки. Библиотека, построенная как MD, была третьей стороной, поэтому я не мог ее перестроить, а библиотека, построенная как MT, имеет много зависимостей, и построить все из них, поскольку MD-большая боль. Я получал ошибку из файла заголовка конфигурации третьей стороны, который сделал его обязательным для создания исполняемого файла как MD. Я искал легкий путь. упаковки сторонних dll в качестве отдельной dll, как упоминалось в вопросе. Тем не менее, я не мог найти достаточно объяснений в интернете на этом простом пути. Отсюда мои два цента ниже. Вот как я его обхожу!--1-->

  1. Я построил еще один .dll, которая действовала как интерфейс. Этот интерфейс в основном обернул все вызовы api,которые были сделаны сторонней dll. Файл заголовка для этого интерфейса не включал какой-либо файл заголовка из сторонней dll, а все эти файлы заголовков были включены в интерфейсе.файл cpp. Интерфейс, как вы ожидаете, был построен как MD.
  2. теперь в моей основной.cpp-файл я включил этот файл заголовка интерфейса, чтобы сделать все вызовы сторонней dll через интерфейс.

  3. необходимо проявлять особую осторожность при передаче аргументов интерфейсу. Основные переменные, такие как int,bool и т. д., могут быть переданы как значение. Однако любой класс или структура должны быть переданы в качестве ссылки const, чтобы избежать повреждения кучи. Это касается даже строка.

рад поделиться более подробной информацией, если это не ясно!