首页 > 解决方案 > 从不同目录中的另一个 dll 加载 dll(在应用程序插件场景中)

问题描述

我正在为另一个应用程序(让我们称之为App )开发一个插件(让我们称之为Cake)。这个插件是用 C++ 编写的并生成一个 dll。启动时,App尝试从其插件文件夹 ( PluginDir ) 加载所有 dll。该文件夹位于与App 的应用程序文件夹 ( 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 添加到Properties -> Linker -> Input -> Delay Loaded Dlls来设置依赖 dll 以延迟加载。为了将CakeDir添加为额外的 dll 搜索路径,我还挂钩了:DllMain

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函数)?

标签: c++windowsvisual-c++dlllinker

解决方案


推荐阅读