Загрузка dll из другой dll в разных каталогах (в сценарии плагина приложения) - PullRequest
0 голосов
/ 19 марта 2020

Я работаю над плагином (назовем его Cake ) для другого приложения (назовем его App ). Этот плагин написан на C ++ и производит DLL. При запуске App пытается загрузить все библиотеки DLL из папки плагинов ( PluginDir ). Эта папка находится по совершенно другому пути, чем папка приложения приложения ( AppDir ). В PluginDir у меня есть ярлык на Cake (который находится в папке CakeDir ). В итоге структура выглядит следующим образом:

AppDir
  |- App.exe

PluginDir
  |- SomeRandomPlugin1.dll
  |- SomeRandomPlugin2.dll
  |- Cake.dll.lnk

CakeDir
  |- Cake.dll
  |- Dependency.dll

В начале Cake.dll не было прямых зависимостей, которые были связаны во время загрузки, и все работало нормально. Теперь у меня есть некоторые зависимости (содержимое CakeDir ), которые связаны во время загрузки, и теперь Cake больше не может быть загружен. Я предполагаю, что это потому, что зависимости DLL находятся в неизвестном пути поиска в соответствии с порядок поиска DLL .

Чтобы противодействовать этому, я установил зависимость dll для отложенная загрузка , добавив зависимость dll в Свойства -> Линкер -> Ввод -> Задержка загруженных DLL . Я также подключил DllMain, чтобы добавить CakeDir в качестве дополнительного пути поиска DLL:

extern "C" BOOL WINAPI DllMain(HINSTANCE const instance, DWORD const reason, LPVOID const /*reserved*/)
{
    switch (reason)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
        {
            OutputDebugStringA("Cake DLL loading...\n");
            const auto pluginDir = getModuleDirectory(instance); // gets CakeDir, also tried to hard code the path, didn't work either
            if (const auto cookie = AddDllDirectory(pluginDir.c_str()))
            {
                g_pluginDirCookie = cookie;
            }
            else
            {
                OutputDebugStringA("Failed to register dll search path.\n");
                return FALSE;
            }
            break;
        }
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        {
            OutputDebugStringA("Cake DLL unloading...\n");
            RemoveDllDirectory(g_pluginDirCookie);
            break;
        }
    }
    return TRUE;
}

Проблема в том, что DllMain никогда не вызывается и не загружается Cake.dll до этого не работает (я полагаю, что отложенная загрузка не работает?).

Что я делаю не так? Как я могу правильно загрузить свои зависимости (без необходимости возвращаться к LoadLibrary и GetProcAddress для каждой отдельной функции)?

...