Windows下多实例加载带依赖DLL:解决单例库多设备连接难题
解决同一进程内加载多实例C.DLL的问题
问题核心
Windows加载DLL时默认按文件名判断是否已加载,而非文件路径。所以即使B、C放在不同目录,只要文件名相同,系统就会复用已加载的实例,导致你无法获得多份C的单例(进而无法同时连接多设备)。
可行解决方案
1. 用LoadLibraryEx替代LoadLibrary,配合特定标志
放弃SetDllDirectory,改用LoadLibraryEx加载每个目录下的A.DLL,指定LOAD_WITH_ALTERED_SEARCH_PATH标志。这个标志会强制系统优先从A.DLL所在目录查找其依赖的B、C,不走全局搜索路径,从而加载对应目录下的B、C实例。
示例代码:
// 加载libs1目录下的A.DLL HMODULE hA1 = LoadLibraryEx(L"libs1\\A.DLL", NULL, LOAD_WITH_ALTERED_SEARCH_PATH); // 加载libs2目录下的A.DLL HMODULE hA2 = LoadLibraryEx(L"libs2\\A.DLL", NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
- 注意:必须传入A.DLL的相对/绝对路径(确保系统能定位到目标目录),否则
LOAD_WITH_ALTERED_SEARCH_PATH不会生效。用绝对路径能避免当前工作目录的干扰,更稳妥。
2. 重命名B、C并修改A的依赖(备选方案)
如果上述方法无效,可尝试:
- 将libs1下的B.DLL、C.DLL重命名为B1.DLL、C1.DLL,libs2下的重命名为B2.DLL、C2.DLL
- 修改对应目录下A.DLL的导入表(或直接修改A的源码,编译时指定链接到重命名后的B、C),让A加载对应目录下重命名后的依赖库。
这样系统会把不同文件名的DLL视为不同模块,自然会加载多实例。
内容的提问来源于stack exchange,提问作者molnarriso
相关产品推荐
相关产品推荐

