Фон
Я поддерживаю плагин для приложения. Я использую Visual C ++ 2003.
Плагин состоит из нескольких DLL - есть основная DLL, та, которую приложение загружает с помощью LoadLibrary, и есть несколько служебных DLL, которые используются основной DLL и друг другом.
Зависимости обычно выглядят так:
- plugin.dll -> utilA.dll, utilB.dll
- utilA.dll -> utilB.dll
- utilB.dll -> utilA.dll, utilC.dll
Вы получите изображение.
Некоторые из зависимостей между библиотеками DLL - время загрузки и время выполнения.
Все файлы DLL хранятся в каталоге исполняемого файла (не требуется, просто как он работает сейчас).
Проблема
Существует новое требование - запускать несколько экземпляров плагина в приложении.
Приложение запускает каждый экземпляр плагина в своем собственном потоке, то есть каждый поток вызывает функции, экспортируемые plugin.dll. Код плагина, однако, совсем не поточнобезопасен - множество глобальных переменных и т. Д.
К сожалению, исправление всего этого в настоящее время не вариант, поэтому мне нужен способ загрузить несколько (не более 3) копий библиотек DLL плагина в одном процессе.
Вариант 1: подход с использованием разных имен
Создание 3 копий каждого файла DLL, чтобы каждый файл имел свое имя. например plugin1.dll, plugin2.dll, plugin3.dll, utilA1.dll, utilA2.dll, utilA3.dll, utilB1.dll и т. д. Приложение загрузит plugin1.dll, plugin2.dll и plugin3.dll. Файлы будут в каталоге исполняемого файла.
Чтобы каждая группа DLL знала друг друга по имени (чтобы работали взаимозависимости), имена должны быть известны во время компиляции - это означает, что библиотеки DLL должны быть скомпилированы несколько раз, только каждый раз с другим выходным файлом. имена.
Не очень сложно, но я бы не хотел иметь 3 копии файлов проекта VS и не хотел бы собирать одни и те же файлы снова и снова.
Вариант 2: сближение сборочных узлов
Создайте 3 копии файлов DLL, каждая группа в своем собственном каталоге, и определите каждую группу как сборку, поместив файл манифеста сборки в каталог со списком DLL плагина.
Каждая DLL будет иметь манифест приложения, указывающий на сборку, так что загрузчик найдет копии служебных DLL, которые находятся в том же каталоге. Манифест должен быть встроен, чтобы его можно было найти при загрузке DLL с использованием LoadLibrary. Я буду использовать mt.exe из более поздней версии VS для этой работы, поскольку VS2003 не имеет встроенной поддержки встраивания манифеста.
Я попробовал этот подход с частичным успехом - зависимости обнаруживаются во время загрузки DLL, но не при вызове функции DLL, которая загружает другую DLL.
Кажется, что это ожидаемое поведение в соответствии с этой статьей - Контекст активации DLL используется только во время загрузки DLL, а затем деактивируется и используется контекст активации процесса.
Редактировать: Работает с ISOLATION_AWARE_ENABLED
, как и ожидалось - загрузка DLL во время выполнения использует исходный контекст активации загружаемой DLL.
Вопросы
Есть другие варианты? Подойдет любое быстрое и грязное решение. : -)
Будет ли ISOLATION_AWARE_ENABLED
работать даже с VS2003? Редактировать: Да.
Комментарии будут высоко оценены.
Спасибо!