【问题标题】:Runtime-load A DLL In The Same Directory (Not The Application Directory)运行时加载同一目录(不是应用程序目录)中的 DLL
【发布时间】:2020-12-06 05:27:03
【问题描述】:

我有一种情况,我需要在运行时(使用LoadLibrary)从同一目录中存在的另一个 DLL (libembed.dll) 加载一个 DLL (libcocotb.dll)。这些 DLL 与应用程序不在同一目录中。

> tree
.
├── ...
├── libcocotb.dll
└── libembed.dll

仅指定库名称LoadLibrary("libcocotb.dll"),未找到该库。 LoadLibrary(".\\libcocotb.dll"),没有找到图书馆。将目录添加到PATH 似乎是错误的答案,我需要在运行时确定目录的位置,因为二进制文件需要可重定位(它们最终会进入 Python 轮子)。

在 Linux 上,我可以将 $ORIGIN 添加到加载 DLL 的 RPATH 中。 Windows上没有类似的东西吗?我对Windows loader和库系统不是很熟悉。

【问题讨论】:

  • 有点难以理解为什么您不想使用 dll 的完整路径。一个简单的解决方案。
  • 我必须计算 dll 的路径。在应用程序运行之前我不知道它在哪里。
  • 在应用程序运行之前您不需要知道它。这是您的解决方案。
  • 那很模糊,你能详细说明一下吗?
  • 什么是模糊的?使用 dll 的完整路径。

标签: windows winapi dll


【解决方案1】:

在 Windows 中执行此操作的一种方法是:

  • 在加载时保存libembed.dllHMODULE,它作为第一个参数传递给它的DllMain entry point

  • 稍后,在准备加载另一个DLL时,使用GetModuleFileName和保存的HMODULE获取libembed.dll的完整路径;

  • 使用PathRemoveFileSpec API 或_splitpath CRT 函数等将libembed.dll 文件名从完整路径中拆分出来;

  • 将生成的目录路径与libcocotb.dll 文件名组合以构建到另一个DLL 的完整路径,例如使用PathCombine_makepath

  • 使用libcocotb.dllLoadLibrary DLL 的完整路径。

【讨论】:

  • 我测试过,这确实有效。对于最终实现,我决定不使用PathRemoveFileSpecPathCombine,因为我不想链接到另一个Windows 库。相反,我使用 C++ 字符串功能拆分文件名,并附加其他库名称。
  • @ktb 这些只是“官方”建议,shlwapi 通常已经被其他组件或库链接。也就是说,当然可以通过直接字符串操作来做到这一点。
猜你喜欢
  • 1970-01-01
  • 2012-05-23
  • 1970-01-01
  • 2021-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多