Я ценю, что подобные вопросы задавались и раньше, но, читая их, ни один из них не полностью решает нашу проблему, поэтому подумал, что попрошу уточнить.
[TL; DR] Версия:
Возможно ли / легко создать оболочку dll для VS2005 CRT, которая затем делегирует все вызовы VS2013 CRT?
Проще ли понизить версию сборки VS2013 так, чтобы она использовала VS2005 CRT?
Или обе эти идеи просто безумны?
Наша ситуация:
Наши приложения C ++ созданы с использованием современных версий компиляторов C ++ (VS2013, gcc 4.8 в зависимости от целевой платформы) - для некоторых из наших зависимостей, которые мы используем, потребуется современная версия, поскольку они используют C ++ 11.
Наши приложения также используют связывание времени выполнения (.dll или .so) для упаковки различных компонентов приложения.
В Windows, чтобы упростить жизнь, мы компилируем с использованием / MD (или / MDd для отладки), т.е. используем CRT в dll с использованием многопоточной версии - любые зависимости, которые мы создаем, перекомпилируются для использования той же CRT.
Использование одного и того же CRT для всех зависимостей (в отдельной dll) означает, что мы избегаем проблем, если память выделяется в одной dll и освобождается в другой, поскольку используется та же куча.
Наша проблема
У нас есть одна зависимость, которая предоставляется третьей стороной (я не буду называть их здесь и позорить их, но вы знаете, кто вы!) В виде предварительно скомпилированной dll, а не в качестве источника.
Он был скомпилирован с использованием VS2005 (MSVC8) в Windows и использует MSVC8 crt.
Их предыдущая версия этой зависимости работала нормально. Их api для этой зависимости правильно обрабатывал выделение и освобождение памяти, поэтому, даже несмотря на то, что он использовал другую версию CRT по сравнению с остальной частью нашего приложения, это не было проблемой.
К сожалению, их новая («улучшенная»!) Версия интенсивно использовала шаблоны C ++ в своем API - эти шаблоны расширяются в нашем вызывающем коде и приводят к попыткам удалить память, выделенную в их dll, из нашего вызывающего кода. Поскольку в двух областях используются разные кучи, это очень проблематично.
Возможные решения:
Чтобы решить эту проблему, мы можем увидеть следующие возможные решения
1] Попросите поставщика переписать (мы просили об этом, и это долгосрочное решение, но не произойдет в ближайшее время)
2] Попросите поставщика повторно скомпилировать с помощью VS2013, чтобы у нас была одинаковая CRT с обеих сторон (очевидно, этого не произойдет - спросили).
3] Используйте VS2005 CRT для всего нашего кода (мы не можем просто использовать VS2005 для создания нашего кода, поскольку у нас есть требование для поддержки C ++ 11)
4] Установите шайбу VS2005 CRT, которую ожидает сторонняя dll, т. Е. Создайте что-то похожее на VS2005 CRT, но на самом деле использующее VS2013 CRT.
5] Оберните стороннюю dll - то есть создайте dll, скомпилированную с VS2005, которая содержит все вызовы сторонней зависимости - и обеспечьте правильную обработку памяти, чтобы она работала с нашими другими (с использованием VS2013 CRT) dll
И напоследок вопрос:
Вариант 5], вероятно, будет наиболее трудоемким (но с наибольшей вероятностью успеха) - в основном это вариант 1], но под нашим контролем, поэтому нам не нужно ждать третьей стороны.
Однако, прежде чем перейти к этому пути, я подумал, что попрошу посмотреть, сделали ли другие что-нибудь похожее на 3] или 4] или какое-то другое решение, о котором мы не думали.
Вариант 4] (создание версии CRT с оболочкой) кажется, возможно, самым простым, поскольку я полагаю, что большая часть работы по обратной совместимости уже будет выполнена в VS2013 CRT - так что это всего лишь случай выяснения деталей и просмотра 2005 версия вызова версии 2013 года - во многих случаях я полагаю, что даже подпись идентична, так что это просто неявная запись.
Однако, когда я просмотрел через Google, я не смог найти ни одного примера, чтобы кто-либо создавал shim dll для проблем несовместимости версий CRT - так что, возможно, это намного сложнее, чем я думаю (или мой google fu сильно не хватает).
Поэтому подумал, что я просто спрошу, делал ли кто-нибудь что-нибудь подобное / знает, почему это действительно глупая идея?