是否有相当于 -rpath 链接器标志的 Windows/MSVC?

问题描述 投票:0回答:4

在 Linux/GCC 上,我可以使用 -rpath 标志来更改共享库的可执行文件搜索路径,而无需使用环境变量进行调整。

这也可以在 Windows 上完成吗?据我所知,dll 总是在可执行文件的目录和 PATH 中搜索。

我的场景:我想根据共享库的属性(32/64位/调试/发布)将共享库放入位置,而不考虑唯一的名称。在 Linux 上,这可以通过 rpath 轻松完成,但我还没有找到在 Windows 上执行此操作的任何方法。

感谢您的任何提示!

windows dll shared rpath
4个回答
29
投票

遗憾的是,没有与 RPATH 直接类似的东西。有许多替代的可能性,每一种都可能以自己特殊的方式不适合您。

鉴于您无论如何都需要为每种构建风格使用不同的 exe,以避免运行时库冲突,因为您可能会猜测最简单的方法是将每个 exe 与每组 DLL 放在同一文件夹中。

正如您还提到的,最通用的方法是通过使用批处理文件引导 exe 来更改 PATH 变量。

您可以在运行程序之前更改当前工作目录到所需的 DLL 文件夹。

您可以在 exe 中使用函数 SetDllDirectoryAddDllDirectory。这可能是最接近 RPATH 的,但仅适用于 WinXP SP1 或更高版本。

如果您愿意更改每个 exe 风格的文件名,可以使用“App Paths”注册表项。每个 exe 都需要一个唯一的文件名。


8
投票

MSDN 上的本页描述了 Windows 中 DLL 的搜索顺序。如果您使用运行时动态链接,则可以在调用

LoadLibrary
时指定文件夹。


7
投票

“隔离的应用程序”是一种嵌入描述 DLL 依赖关系的 XML 清单的机制。


0
投票

我发现的最好的技巧就是这里描述的:

https://devblogs.microsoft.com/oldnewthing/20170126-00/?p=95265

使用起来很麻烦,但它比 UNIX 更强大

-rpath
,因为它允许动态生成路径,同时保留隐式链接的所有好处。

我在这里使用它: https://github.com/mmomtchev/meson-xpack/blob/main/wrappers/wrapper.c#L8-L35

这是完整的示例:

HMODULE LoadPython() {
  static char path[4096];
  const char *root;

  snprintf(path, 4096, "%s/%s/%s", root, PYTHON_PATH, PYTHON_DLL);
  return LoadLibraryA(path);
}
FARPROC WINAPI delayHook(unsigned dliNotify, PDelayLoadInfo pdli) {
  if (dliNotify == dliNotePreLoadLibrary && strcmp(pdli->szDll, PYTHON_DLL) == 0) {
    return (FARPROC)LoadPython();
  }
  return NULL;
}
ExternC const PfnDliHook __pfnDliNotifyHook2 = delayHook;
ExternC const PfnDliHook __pfnDliFailureHook2 = delayHook;

然后将您的程序链接到

/DELAYLOAD:"python312.dll"

普通的旧C,在链接器级别启用DLL的延迟加载,然后注册一个拦截加载的钩子。

© www.soinside.com 2019 - 2024. All rights reserved.