在Python中加载具有依赖项的DLL
我有一个依赖于另一个dll的在Python中加载具有依赖项的DLL,python,c++,dll,loadlibrary,Python,C++,Dll,Loadlibrary,我有一个依赖于另一个dll的proj1.dll,proj2.dll。在VS2013中编译proj2.dll时,我根据编译器输出的导入库编译了proj1.dll。我还导出了我感兴趣使用的公共函数。现在我有两个独立的DLL,它们都符合“cdll”标准 我想在Python中使用proj1.dll,但遇到以下问题: import ctypes # Crashes saying no entry point for "some_func" in proj2.dll ctypes.cdll.LoadLib
proj1.dll
,proj2.dll
。在VS2013中编译proj2.dll
时,我根据编译器输出的导入库编译了proj1.dll
。我还导出了我感兴趣使用的公共函数。现在我有两个独立的DLL,它们都符合“cdll”标准
我想在Python中使用proj1.dll
,但遇到以下问题:
import ctypes
# Crashes saying no entry point for "some_func" in proj2.dll
ctypes.cdll.LoadLibrary("C:\myfolder\proj1.dll")
ctypes.cdll.LoadLibrary("C:\myfolder\proj2.dll") # Loads fine
ctypes.cdll.LoadLibrary("C:\myfolder\proj1.dll") # Loads fine if proj2 is loaded first
以前,当我将proj2
构建为一个静态库并在proj1
中与之链接时,从Python调用此DLL是有效的。这两个DLL存在于同一文件夹中。我甚至尝试将文件夹的路径添加到我的path环境变量中,以查看这是否是路径问题,但没有任何更改
我假设Windows将加载
proj1.dll
,然后加载dll的依赖项。我错了吗?调用方(Python)必须首先加载依赖项DLL吗?有人知道为什么会发生这种情况吗?您需要确保您的环境路径包含指向依赖项的路径。这会奏效的
import os
from ctypes import *
path_to_deps = "C:\\myfolder"
os.environ['PATH'] = path_to_deps + os.pathsep + os.environ['PATH']
d = CDLL("C:\myfolder\proj2.dll")
更新:
在调用
os.add\u dll\u目录(路径)
中已添加,用于指定要搜索的dll目录。可能需要更改项目的生成设置
看看这是否有帮助:列表
考虑到问题提出的时间,可以排除Python 3.8(但可能仍然很有趣)
对于.dll加载泛型,可能包含有用的信息
现在,这个问题不完全是MCVE或REPREX(),但我假设如果是,答案可能是显而易见的,因此不需要这个问题:)
调查
错误为未找到错误进程(127,0x7F)
注意:只有在成功加载了.dll的所有依赖项(递归)后,才会加载.dll。如果其中一个依赖项失败,则故障将一直传播到顶部,并且(原始).dll加载失败并出现该错误
在这两种情况下(自动)会发生什么情况:
- 成功:
- 找到并尝试加载项目J2。它成功了
- 发现有人试图加载proj1
- 由于这取决于项目J2,因此尝试首先加载该项目
- proj2已在内存中(从#1)
- proj2中搜索proj1所需的proj2函数。他们都找到了
- 故障:
- 发现有人试图加载proj1
- 由于这取决于项目J2,因此尝试首先加载该项目
- 找到并加载了proj2(如果没有找到,则错误为错误MOD\U NOT\U found)
- proj2中搜索proj1所需的proj2函数。显然,(至少)一个没有找到,程序崩溃了
因此,这一步骤(#2.)也成功了
它不是C:\myfolder\proj2.dll。它可能是一个没有导出所需函数的旧版本,或者是另一个完全不相关的版本 我用2个简单的(依赖的).dll和一个.exe(如果需要,我还会发布代码)成功地重现了崩溃: 最简单的解决方案是在加载proj1.dll之前,将“C:\myfolder”即proj2.dll(右侧)的目录添加到%PATH%。检查并记住以下方面:
- 追加它(在末尾)将不起作用,因为错误的.dll目录已经在%PATH%(在右边的目录之前)中,并且将首先找到(并加载)错误的.dll
- 您必须将其添加到错误目录之前(或者更好:从%PATH%中删除错误目录)。要检查其位置,请使用(cmd)终端:
where proj2.dll
- 由于我不知道%PATH%中错误的.dll目录位置在哪里,因此在%PATH%的开头添加正确的.dll目录就可以了。就个人而言,我并不认为在赢得系统目录之前准备好目录是一个很好的实践[P/>
- 但是,如果proj2.dll位于“%SystemRoot%\System32”下,则必须删除(或重命名)它(文件)
- 在启动Python之前:
set PATH=C:\myfolder;%路径%
- 从Python本身来看:
对于Python3.8,请检查答案开头的相关URLos.environ[“PATH”]=“C:\myfolder;”+os.environ[“PATH”]
(静态)dll依赖项检查的一个很好的工具是。路径中是否有
myfolder
?您可能需要检查proj1.dll
,以确认它包含依赖项。Python版本是什么?有什么错误?@CristiFati我不确定OP是否还可以回答你的问题。我确实打开了《赏金》,因为我有一个非常类似的问题(),并且认为这个问题的更完整的答案也会回答我的问题(如果在这里发布了一个好的答案,我会将我的问题作为副本关闭)。请随意检查另一个问题并在那里提问,也许我会用另一种方式来回答。@Holt:所以,这是一个与所指问题不同的问题。