Python错误集锦:cytpes加载dll文件时FileNotFoundError: Could not find module ‘pytest.dll’ (or one of its dependencies). Try using the full path with constructor syntax.

原文链接:http://www.juzicode.com/python-error-cytpes-filenotfounderror-could-not-find-module-try-using-full-path

错误提示:

cytpes加载dll文件时FileNotFoundError: Could not find module ‘pytest.dll’ (or one of its dependencies). Try using the full path with constructor syntax.

C代码:

// juzicode.com/ VX: 桔子code   
#include "stdio.h"
#ifdef __cplusplus
extern "C" {
#endif 
 
__declspec(dllexport) int addint(int x, int y)
{
	return x + y;
}

#ifdef __cplusplus
}
#endif            

Python代码:

# juzicode.com/ VX: 桔子code  
from ctypes import *
pyt = CDLL('pytest.dll')  
pyt.addint.restype=c_int     
pyt.addint.argtypes=(c_int,c_int)
z = pyt.addint(10,20)          
print('z =',z) 
==========运行结果:
Traceback (most recent call last):
   File "ctypes-test.py", line 3, in 
     pyt = CDLL('pytest.dll')
   File "D:\Python\Python38\lib\ctypes__init__.py", line 373, in init
     self._handle = _dlopen(self._name, mode)
 FileNotFoundError: Could not find module 'pytest.dll' (or one of its dependencies). Try using the full path with constructor syntax.

 

py文件和dll文件在同一个路径下:

错误原因:

1、dll和py文件已经在当前工作路径下,仍然提示没有找到dll文件,有可能pytest.dll文件还有别的依赖,但是从C代码看除了标准库文件,并没有调用其他的dll。从提示信息Try using the full path with constructor syntax. 看,建议使用完整路径。

 

解决方法:

1、dll文件名称补齐工作路径,可以添加当前工作路径

# juzicode.com/ VX: 桔子code  
from ctypes import *
pyt = CDLL('.\\pytest.dll')  #补齐当前工作路径
pyt.addint.restype=c_int     
pyt.addint.argtypes=(c_int,c_int)
z = pyt.addint(10,20)          
print('z =',z) 
==========运行结果:
z = 30

2、使用os.add_dll_directory()补齐完整路径,依据当前py文件路径计算绝对路径,传入到os.add_dll_directory(),计算绝对路径的方法见:《非工作路径、非入口路径如何导入Python自定义模块》。这种方式灵活性更高,不依赖于当前工作路径。需要注意的是os.add_dll_directory是Python3.8新加的特性。

# juzicode.com/ VX: 桔子code  
from ctypes import *
import os,sys
add_path = os.path.split(os.path.abspath(__file__))[0]+'\\'
os.add_dll_directory(add_path) #添加dll搜索路径
pyt = CDLL('pytest.dll')  
pyt.addint.restype=c_int     
pyt.addint.argtypes=(c_int,c_int)
z = pyt.addint(10,20)          
print('z =',z) 
==========运行结果:
z = 30

 需要注意的是并不能使用当前路径作为add_dll_directory()的入参,否则会出现OSError:

Traceback (most recent call last):
   File "ctypes-test2.py", line 5, in 
     os.add_dll_directory('.\\')
   File "D:\Python\Python38\lib\os.py", line 1109, in add_dll_directory
     cookie = nt._add_dll_directory(path)
 OSError: [WinError 87] 参数错误。: '.\\'

3、直接在加载时指定完整路径,这种方法不依赖Python版本必须是3.8以上:

# juzicode.com/ VX: 桔子code  
from ctypes import *
import os,sys
add_path = os.path.split(os.path.abspath(__file__))[0]+'\\'
#os.add_dll_directory('.\\')
pyt = CDLL(add_path+'pytest.dll')  
pyt.addint.restype=c_int     
pyt.addint.argtypes=(c_int,c_int)
z = pyt.addint(10,20)          
print('z =',z) 
==========运行结果:
z = 30

扩展内容:

  1. Python进阶教程m7–混合编程–调用可执行文件
  2. Python进阶教程m7b–混合编程–C语言接口ctypes(1)
  3. Python进阶教程m7c–混合编程–C语言接口ctypes(2)
  4. Python进阶教程m7d–混合编程–代码级扩展
  5. 非工作路径、非入口路径如何导入Python自定义模块

 


 

如果本文还没有完全解决你的疑惑,你也可以在微信公众号“桔子code”后台给我留言,欢迎一起探讨交流。

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注