QT C++中调用python脚本时,import第三方库失败问题解决
QT C++中调用python脚本时,import第三方库失败问题解决
文章目录
前言
项目需要,计划通过C++的QT调用Python脚本,实现更快的算法实现,并集成在项目软件上。但是,在按照网上教程,配置好C++调用Python脚本的环境后,在调用(import)对应路径下的py文件时,基本没有问题。但是,一旦调用numpy、matplotlib时,则PyImport_ImportModule函数即会返回失败! 因此,这里重点针对import第三方库,却PyImport_ImportModule失败的问题,进行解决。关于配置C++调用Python脚本的环境,参考上述链接即可,并不复杂。
一、问题复现
首先,对具体问题进行更加细致的复现。在C++代码中,具体代码如下。
// 1. 设置Python的运行环境目录
Py_SetPythonHome(L"D:/Software/anaconda3/envs/xxxx");
// 2. 初始化python解释器
Py_Initialize();
// 2.1 检查初始化是否成功
if (!Py_IsInitialized()) {
qDebug() << "Python init fail";
Py_Finalize();
}
// 3.1 执行Python脚本语句
PyRun_SimpleString("print('I am Python!')");
// 3.2 初始化python系统文件路径,保证可以访问到 .py文件
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('E:/Code/xxxx/')");
// 3.3 将文件作为模块,import导入,不需写后缀
PyObject* pModule = PyImport_ImportModule("MyTest");
if (pModule == NULL) {
qDebug() << "module not found";
return;
}
// 3.4 调用函数
PyObject* pFunc = PyObject_GetAttrString(pModule, "test");
if (!pFunc || !PyCallable_Check(pFunc)) {
qDebug() << "not found function test";
return;
}
在这里,MyTest.py文件内,代码如下。
import numpy as np
from matplotlib import pyplot as plt
import time
import math
def test():
print("hello!")
此时,若将MyTest.py中import的四个模块语句注释,则程序没有任何问题,正常运行。但是,若不注释那四句,则 PyObject* pModule = PyImport_ImportModule(“MyTest”)会返回NULL。这时,便会给我们产生错觉:似乎该环境下,调用通过pip install安装的第三方库,便会失败,即需要进一步配置这些第三方库的环境。
二、调试过程
首先,便是按照上述思路,进行百度谷歌寻找答案,主要是配置python的库文件的环境变量等,这里不赘述,总之,这并不能解决问题!
后来,突然发现,在C++代码中,有这么一句:
PyRun_SimpleString("import sys");
调试发现,该句代码是成功运行的,所以,便推倒前述结论:该环境下,调用通过pip install安装的第三方库,便会失败。那么,也就是说,仅是上述的某些库,import失败了,而非所有第三方库!于是,分别对MyTest.py中的import部分代码轮流注释,如下:
import numpy as np
# from matplotlib import pyplot as plt
# import time
# import math
def test():
print("hello!")
结果发现,当单独import time与math时,PyObject* pModule = PyImport_ImportModule(“MyTest”)返回并不为空,也就是说是导入成功的!因此,可以正确推出结论:PyImport_ImportModule在执行Import numpy与matplotlib时,会失败。 但是,为什么会失败呢?仅从上述代码中的返回结果,仍然无法看出错误原因。于是,修改C++代码,将下述两行代码,加入到PyRun_SimpleString(“import sys”)之后。
PyRun_SimpleString("import numpy");
PyRun_SimpleString("import matplotlib");
于是,背后真正的错误便迎面儿来了。当import numpy时,错误为:
and make sure that they are the versions you expect.
Please carefully study the documentation linked above for further help.
Original error was: DLL load failed while importing _multiarray_umath: 找不到指定的模块。
当import matplotlib时,错误为:
ImportError: cannot import name 'Image' from 'PIL' (unknown location)
三、问题解决
其实,当背后错误出现时,再解决问题就很好办了,对应去搜背后错误的解决方法即可。我相应参考numpy问题解决与matplotlib问题解决,两个问题便都迎刃而解了。这里总结一下。
1 numpy问题解决
重新安装numpy即可:
pip uninstall numpy
pip install numpy
2 matplotlib问题解决
pip uninstall pillow
pip install pillow
可以发现,都是通过重新安装库或者关键依赖库后,问题得以解决!至于具体原因是什么,还不是非常清楚,也由于时间问题,就不深入挖掘了,希望后续有大佬搞清楚以后,欢迎交流讨论!
四、补充说明
本部分,为后续补充内容。在完成本篇博客后,后续项目推进上,又碰到了很多类似问题,例如同样在C++调用Python拓展模块时,报错:
ImportError: DLL load failed while importing cv2: 找不到指定的模块。
此时,我按照本文提出方法,卸载opencv后继续安装,也进一步安装了opencv-contrib-python模块等,均未解决问题。后来考虑,是否为opencv版本太高呢,于是将opencv降版本至4.5.1.48,问题解决!至此,大概可以为为本文的问题形成一个结论:当出现找不到指定模块、DLL加载失败等类似问题时,可考虑一种很大可能性,是该库的版本与环境不匹配,可能版本太旧,但同样也可能版本太新!此时,可调整几个版本测试,很多类似问题可能也就此解决了!
另外,在本部分的研究内容中,需要自行编译支持gstreamer编码器的opencv,感觉这类opencv库应该需求量很大,但是却没有人提供编译好的库,故此在这里提供链接。
五、参考资料
最后,感谢各位大佬提供的前人经验:
[1] alxe_made: Qtcreator中C++调用python方法
[2] HJ: 成功解决ImportError: cannot import name ‘image‘ from ‘PIL‘(unknown location)
[3] 衷科知眠: 成功解决ImportError: cannot import name ‘image‘ from ‘PIL‘(unknown location)
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!