2010-08-12 3 views
6

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

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

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

К сожалению, я Запретный принимать легкий вариант упаковки стороннего программного кода в отдельный DLL: -/

ответ

3

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

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

Source

+0

Не тот ответ, на который я надеялся, но спасибо ;-) – slowdog

0

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

0

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

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

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

С удовольствием сообщаем более подробную информацию, если это непонятно!

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