смешанный код, скомпилированный с / MT и / MD - PullRequest
6 голосов
/ 12 августа 2010

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

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

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

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

Ответы [ 3 ]

3 голосов
/ 12 августа 2010

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

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

Источник

1 голос
/ 01 декабря 2016

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

0 голосов
/ 23 сентября 2017

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

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

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

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

...