在Python中加载具有依赖项的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

我有一个依赖于另一个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.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函数。他们都找到了

  • 因此,这一步骤(#2.)也成功了

  • 故障

  • 发现有人试图加载proj1
  • 由于这取决于项目J2,因此尝试首先加载该项目
  • 找到并加载了proj2(如果没有找到,则错误为错误MOD\U NOT\U found)
  • proj2中搜索proj1所需的proj2函数。显然,(至少)一个没有找到,程序崩溃了
从上面可以看出,在%PATH%中的某个地方有一个proj2.dll,当加载proj1.dll时,操作系统会自动加载该proj2.dll
它不是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”下,则必须删除(或重命名)它(文件)
无论如何,%PATH%更改可以通过以下任一方式完成:

  • 在启动Python之前:

    set PATH=C:\myfolder;%路径%
    
  • 从Python本身来看:

    os.environ[“PATH”]=“C:\myfolder;”+os.environ[“PATH”]
    
    对于Python3.8,请检查答案开头的相关URL


(静态)dll依赖项检查的一个很好的工具是。

路径中是否有
myfolder
?您可能需要检查
proj1.dll
,以确认它包含依赖项。Python版本是什么?有什么错误?@CristiFati我不确定OP是否还可以回答你的问题。我确实打开了《赏金》,因为我有一个非常类似的问题(),并且认为这个问题的更完整的答案也会回答我的问题(如果在这里发布了一个好的答案,我会将我的问题作为副本关闭)。请随意检查另一个问题并在那里提问,也许我会用另一种方式来回答。@Holt:所以,这是一个与所指问题不同的问题。