Фон
Я поддерживаю плагин для приложения. Я использую Visual C++ 2003.Загрузка нескольких копий группы DLL в тот же процесс
Плагин состоит из нескольких 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.
Это, по-видимому, ожидаемое поведение в соответствии с this article. Контекст активации DLL используется только во время загрузки DLL, а затем он дезактивируется и используется контекст активации процесса.
Редактировать: Работает с ISOLATION_AWARE_ENABLED
как и ожидалось - загрузка DLL в режиме загрузки использует исходный контекст активации загружаемой DLL.
Вопросы
Есть другие варианты? Любое быстрое & грязное решение будет делать. :-)
Будет ли ISOLATION_AWARE_ENABLED
даже работать с VS2003? Редактировать: Он делает.
Комментарии будут оценены с большой благодарностью.
Спасибо!
ISOLATION_AWARE_ENABLED фактически делает работу с VS2003, я думаю, SDK, который поставляется с ним был достаточно недавнее включить Winsxs поддержки. Мне не было известно о внедрении манифестов с использованием файла .rc - спасибо за информацию. – george