import cv2 DLL Load Failed 错误原理与解决方案
在上一篇vs2015+cuda+anaconda源码编译opencv的博客里,arieslady小姐姐已经提到过编译出的pyd文件并不是全部的opencv库的内容,而是要在运行时(也就是import的时候)dynamic的去加载编译出的形如opencv_*.dll的动态链接库。如果1)这些opencv_*.dll文件本身不在.pyd文件的搜索路径中;2)这些opencv_*.dll所依赖的动态链接库不在搜索路径中,那么在python命令行中import该.pyd文件时就会抛出一个非常ugly的DLL Load Failed错误。
同时小姐姐也提到了这时候我们应该1)确定opencv_*.dll文件都在path的搜索路径之下;2)打开vs2015开发人员命令提示工具,切换到.pyd文件的根目录下,输入dumpbin cv2.cp35-win_amd64.pyd /dependents命令列出该动态链接库所依赖的所有动态链接库,查看是否有没有包含在路径里的dll;3)如果列出的动态链接库都在搜索路径之下,但还是不能import,就打开CMake,将BUILD_SHARED_LIBS取消勾选,即以静态库的方式编译opencv python binding,这时会编译出一个super fat的.pyd文件(包含cuda, tbb一共800MB左右),然后重新执行第二步,确保列出的所有dll文件都在搜索路径中。
那么怎么知道缺失的是哪些动态链接库呢?如果人工一个个去path路径下去寻找,那么大家可能在C:\Windows\System32目录下已经晕菜了。不过好在arieslady小姐姐帮大家写了一个找动态链接库的python脚本get_missing_dlls.py,只要将dumpbin输出的动态链接库保存到一个文本文件,如dependencies.txt中,并以换行符隔开(前后可以有空格),然后在终端输入python get_missing_dlls.py dependencies.txt,在终端上就会自动为大家打印出缺失的动态链接库数量与名称喔!
#copyright: arieslady
import os
import sys
def get_path_list():
'''get path list from environment variable path'''
path_list = os.environ['path'].split(os.pathsep)
path_list = [path for path in path_list if path is not '']
return path_list
def load_required_dll_names(filename,sep='\n'):
'''read required dll dependency names from file,
different names are seperated by sep'''
with open(filename,"r") as f:
content = f.read().strip().split(sep)
required_dlls = [dll.strip() for dll in content]
return required_dlls
def find_missing_dlls(required_dlls, path_list):
'''given requied dlls and enviroment variable "path" from system
return those dlls that are not searchable in path'''
missing_dlls = []
for dll in required_dlls:
found_dll = False
for path in path_list:
if os.path.exists(os.path.join(path,dll)):
print(os.path.join(path,dll))
found_dll = True
break
if found_dll == False:
missing_dlls.append(dll)
return missing_dlls
def print_missing_dlls(missing_dlls):
if(len(missing_dlls) == 0):
print("No dlls missing!")
else:
print("There are {0} dlls missing_dlls!".format(len(missing_dlls)))
[print(dll) for dll in missing_dlls]
if __name__ == '__main__':
argv = sys.argv[1:]
if(len(argv)!=1):
print("usage: python get_missing_dlls DLL_DEPENDENCY_FILENAME")
exit()
dependency_filename = argv[0]
path_list = get_path_list()
required_dlls = load_required_dll_names(dependency_filename)
missing_dlls = find_missing_dlls(required_dlls, path_list)
print_missing_dlls(missing_dlls)
本博客由arieslady_csu_zyc原创,拒绝一切形式的转载