Почему мое приложение на C ++ не может найти мой C# плагин в папке плагинов? - PullRequest
0 голосов
/ 04 августа 2020

Приложение

У меня есть приложение, написанное на C ++.

Оно живет в C:\app\app.exe

Плагины

Приложение может быть расширено с помощью плагинов. Плагины - это библиотеки DLL, написанные на C ++. У меня нет доступа к исходному коду для app.exe

Плагины живут в C:\app\plugins

app.exe используют Windows функции LoadLibraryExW и GetProcAddress для загрузки функций в библиотеки DLL плагина (библиотеки DLL плагина и имена функций указываются пользователем во время выполнения).

Generi c Plugin

Существует общий c плагин, который может запускать плагины, написанные на C#. Этот общий c плагин имеет такую ​​структуру:

  1. Класс C ++ под названием GenericPlugin. -> создает GenericPlugin.dll (неуправляемую DLL)
  2. Класс C ++ / CLI с именем PluginLoader -> создает PluginLoader.dll
  3. A C# класс с именем Tools -> создает Tools.dll (управляемый DLL)

GenericPlugin вызывает PluginLoader, который вызывает Tools.

Tools использует System.Reflection.Assembly.LoadFrom и Reflection (для поиска всех DLL (например, SomeDotNetPlugin.dll) с классами stati c с методами с настраиваемым атрибутом. Я не могу выполнить код C ++ / CLI или C#.

Итак, структура папок / файлов выглядит так

C:\app\app.exe
C:\app\plugins\GenereicPlugin.dll
C:\app\plugins\PluginLoader.dll
C:\app\plugins\Tools.dll
C:\app\plugins\SomeDotNetPlugin.dll

Проблема

Когда я запускаю app.exe, приложение вылетает.

Использование Windows Process Monitor ,

  1. Я вижу, что app.exe может найти GenereicPlugin.dll и PluginLoader.dll в папке плагинов.
  2. Но app.exe не удается найти. NET Tools.dll. Согласно Process Monitor, app.exe ищет только C:\app для Tools.dll, но не C:\app\plugins

. В качестве теста я поместил Tools.dll и SomeDotNetPlugin.dll в C:\apps. Теперь DLL найдена, но app.exe по-прежнему не работает. Монитор процессов не сообщает мне, что не так.

Вопросы

  1. Как диагностировать эту проблему?
  2. Почему app.exe не заглядывать в папку плагинов, чтобы найти. NET C# управляемую DLL?

Код Здесь очень кратко вызовы, используемые в app.exe и плагинах.

app.exe

LoadLibraryExA( libName, NULL,  0);
...
static_cast< void * >( ::GetProcAddress( library_, symbolName ) );
...

GenericPlugin.dll

auto functionList = PluginLoader::listNetFunctions();

PluginLoader.dll

auto functions = Tools::listFunctions();

Tools.dll

string DirPath = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

var di = new System.IO.DirectoryInfo(DirPath);
var fi = di.GetFiles("plugins\\*.dll");

foreach (var f in fi) {

    var a = System.Reflection.Assembly.LoadFrom(f.FullName);              
    var types = a.GetTypes();
    var dm = buildDelegateMap();

    foreach (var t in types)  {
        foreach (var m in t.GetMembers())  {
            var ea = m.GetCustomAttribute<CustomFunctionAttribute>();      
            var mi = m as MethodInfo;
            string methodSignature = getMethodSignatureString(mi);
            Delegate d = Delegate.CreateDelegate(dm[getMethodSignatureString(mi)], mi);
            var fp = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate(d);
            ...
            //store fp in dictionary ea.Name -> fp
            ...                                
...