2

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

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

有没有一个干净的解决方案?

这是我尝试过的代码:

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)
4

1 回答 1

2

看来这是 Windows 7 的问题。此处的讨论提供了更多详细信息。

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

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

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

于 2018-10-04T14:22:26.227 回答