Windows下Python中常见的几种DLL load failed问题的原因以及解决方案...
发布网友
发布时间:2024-10-23 23:31
我来回答
共1个回答
热心网友
时间:2024-11-09 16:28
在深度学习流行的今天,深度学习的框架大多基于Python实现,或者提供了Python接口。为了确保性能,底层计算通常使用C/C++实现。对于C/C++项目,其链接方式主要分为以下两种:
在Windows下大多数深度框架中,大多采用动态链接方式。其原因在于...
在动态链接方式的第三个特点中,我们说到了分发时可能会产生问题。这类问题通常被称为"DLL Hell"。以下是一个场景:
程序P1依赖于库L的一个版本L1。用户为了使用P1,将L1放在系统目录中。然而,有一天用户又需要使用程序P2,而P2依赖于库L的另一个版本L2。假设L1和L2无法兼容,那么用户就无法同时使用P1和P2。
为了解决这一问题,有以下几种解决方法...
虽然方法2看似不错,但它依赖于一个命名规则。一方面不是强制要求,另一方面仅适用于开发者调试,非常不方便。而对于方法1,如果某个程序仍然将库安装到系统目录,那还是会造成问题。如果我们可以额外设定一些信息来辅助动态链接库的查找,那么问题就迎刃而解了。这个信息在Unix中被称为RPATH,在编译链接时指定,对于.NET平台,则可以新建一个.config文件来指定动态链接库的目录。
遗憾的是,由于Windows平台背负着沉重包袱,没有类似引入这样的解决方法。此外,由于没有统一的包管理器,因此方法2也无法使用。即使我们采用了方法1,也无法保证程序可以正确加载所有依赖库。在一般情况下,在DLL加载失败时,Windows会弹出一个消息框来提醒用户哪个DLL加载失败了。但是,Python为了保证代码不会被UI阻塞,因此将这个消息框弹出的消息屏蔽了,这使得调试这个问题变得更加复杂。
接下来,我们将具体介绍这个问题的产生原因以及解决方法。在介绍Python下常见的几种DLL load failed错误之前,我们可以将其分为两种类型...
下面将介绍一些常见的DLL加载调试工具,我们将这些工具按大小以及复杂性升序排序,并依次进行介绍...
错误的调试方法...
其实,作为Python自身也在考虑如何解决这个问题。从Python 3.8开始,引入了os.add_dll_directory这个API。也就是说对于环境变量PATH中的目录,不再能影响DLL的加载过程了。当然,并不是所有Python发行版都是这样做的,比如Anaconda还是保留了原有的加载逻辑。当然,还有一个非常exciting的改进,就是Python不再对DLL加载失败的弹窗进行屏蔽了。这样用户可以更容易地知道哪个DLL的加载出了问题,而不需要借助外部工具。当然,我也希望微软也能在编译工具进行改进,无论是引入RPATH,或是运行时读取配置文件,只要能动态通过非环境变量的方式对DLL加载的路径进行设置,相信都能使Python中使用C/C++扩展的库在Windows上的体验更上一层楼。