У меня есть прикладная среда, которая по сути является плагином, где:
хост-приложение вызывает в неуправляемую c ++ dll, которая вызывает в управляемую C ++ dll, которая вызывает в C # dll
Это довольно известный способ вызова C # из неуправляемого C ++ с использованием моста управляемого C ++. Все это работает хорошо и хорошо в большинстве случаев, за исключением архитектуры с подключаемым типом, в которой мои dll (неуправляемые C ++, управляемые C ++ и C #) не находятся в том же каталоге, что и приложение, вызывающее dll. Когда приложение вызывает неуправляемый C ++, все хорошо, потому что приложение знает каталог для вызова, чтобы загрузить эту DLL. Однако в первый раз, когда неуправляемый C ++ вызывает управляемый C ++, мы получаем исключение FileNotFoundException. Оказывается, он не находит C # dll (отмечая, что все три dll находятся в одном каталоге, а не в каталоге приложения). Если я помещаю все dll в каталог времени выполнения exe, то все работает отлично, и мы не получаем исключение FileNotFoundException. Но при развертывании у меня не будет контроля над вызывающим приложением, и поэтому я не смогу удалить свои dll в каталог времени выполнения.
Итак, вопрос в том, как я могу в неуправляемом коде C ++ программно установить каталог загрузки для C # dll при загрузке управляемого C ++ dll? Я попробовал SetDllDirectory и установил переменную пути в системе безуспешно для каталога, в котором находятся мои библиотеки.
По умолчанию CLR просматривает сборку только в двух местах: сначала GAC, затем каталог, из которого запускается EXE. Чтобы найти его в другом месте, требуется дополнительная работа. Одна возможность не включена, вы не можете подписать обработчик событий для AppDomain.AssemblyResolve в этом сценарии. Что оставляет файл app.exe.config с <probing>
или же <codebase>
элементы. Вы должны дать ему то же имя, что и неуправляемый EXE-файл, и сохранить его в той же папке, что и EXE-файл.
Это имеет тенденцию быть неразумным, если EXE-файл не принадлежит вам, и не совсем решает проблему сохранения содержимого в каталоге EXE-файла. GAC — это простой обходной путь.
Других решений пока нет …