【问题标题】:Loading symbols from a DLL loaded with a non-standard path that forward to another DLL从使用非标准路径加载的 DLL 加载符号,该路径转发到另一个 DLL
【发布时间】:2019-03-09 18:18:55
【问题描述】:

我正在尝试动态加载不在正常搜索路径上的 DLL (python3.dll)。我可以使用更改的搜索路径加载它,但是当我执行 GetProcAddress 时,它失败了(因为我正在加载的函数转发到另一个 DLL,python37.dll)。

我认为我需要做的是让 GetProcAddress 遵循与我原来的 DLL 加载中相同的搜索逻辑,但我不知道如何在不改变系统 PATH 的情况下做到这一点(它有各种各样其他潜在问题,因为我的代码继续让用户运行他们自己的代码,这需要 original 路径)。

有没有干净的解决方案?

这是我尝试过的代码:

HMODULE py_dll = LoadLibraryW(L"python3.dll");
if (!py_dll) {
    py_dll = LoadLibraryExW(L"C:\\Work\\Projects\\pylaunch\\py3embed\\python3.dll", NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
}

if (!py_dll) {
    printf("Cannot load Python DLL\n");
    err();
    return 1;
}
char buf[1000];
GetModuleFileName(py_dll, buf, 1000);
printf("DLL is %s\n", buf);
Py_Main_t Py_Main = (Py_Main_t)GetProcAddress(py_dll, "Py_Main");
if (!Py_Main) {
    printf("Cannot load Py_Main\n");
    err();
    return 1;
}

添加 SetDllDirectory() 似乎没有帮助,但我只是将一个调用转储到代码中,因为我不是 100% 清楚它是如何工作的,所以我可能做错了什么。

供参考,Py_Main符号的定义是

 747  2EA          Py_Main (forwarded to python37.Py_Main)

【问题讨论】:

  • 从未使用过 pylaunch,但我感觉 python3.dll 是一个 shim,它引用了真正的 Python3 i> 一。为什么不直接加载引用的.dll?另外,你能发布 SetDllDirectory 代码吗? python3.dll 指向 python35.dll (无论它位于何处)时是否存在任何情况?
  • 你的场景让我怀疑你的 python 安装是否顺利。是标准安装吗?如果您认为这可能是个问题,这里是 some conversations down that path。 (处理 other python,但路径仍然是任何语言的路径。)
  • @CristiFati python3.dll 是 Python 发行版的一部分,它将所有引用转发到 python37.dll。需要它以便您的代码可以加载(次要)版本独立的 DLL 并使用任何 Python 版本。有关详细信息,请参阅 PEP 384。 SetDllDirectory 代码无非就是SetDllDirectoryW(L"C:\\Work\\Projects\\pylaunch\\py3embed");LoadLibrary 之前)。
  • @ryyker 安装是标准嵌入式 Python 发行版的副本。很好听(适用于其他嵌入式应用)。
  • 您使用的是哪个 Python37 安装程序,32 位还是 64 位?我想知道systemSysWoW64 位置是否是LoadLibrary_x_ 函数默认搜索行为的一个因素。

标签: c windows dll getprocaddress


【解决方案1】:

这似乎是 Windows 7 的问题。讨论 here 提供了更多详细信息。

基本上,GetProcAddress 在加载其他 DLL 以解析转发的符号时似乎不尊重使用 SetDllDirectory 对搜索路径所做的更改。如果包含转发符号的 DLL 对目标 DLL 有依赖关系,它确实工作,但 python3.dll 没有这种依赖关系。

从上面链接的 Python 问题中的报告看来,此行为已在 Windows 10 中得到修复,因此您需要在 Windows 7 上才能看到问题。

解决方案似乎是更新 Windows,或者避免将 GetProcAddress 与转发函数一起使用(除非转发器依赖于目标)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-28
    • 1970-01-01
    • 1970-01-01
    • 2020-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多