错误提示:
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
扩展内容:
- Python进阶教程m7–混合编程–调用可执行文件
- Python进阶教程m7b–混合编程–C语言接口ctypes(1)
- Python进阶教程m7c–混合编程–C语言接口ctypes(2)
- Python进阶教程m7d–混合编程–代码级扩展
- 非工作路径、非入口路径如何导入Python自定义模块
如果本文还没有完全解决你的疑惑,你也可以在微信公众号“桔子code”后台给我留言,欢迎一起探讨交流。