【发布时间】: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 位?我想知道
system与SysWoW64位置是否是LoadLibrary_x_函数默认搜索行为的一个因素。
标签: c windows dll getprocaddress