最近在做的东西中需要在C++中调用Python的代码,遇到了一些问题,期间尝试用了各种搜索引擎,花费了十几个小时才解决,真感觉智商是个好东西,可惜自己没有/(ㄒoㄒ)/~~,所以把自己遇到的问题记录下来,没准可以帮到别人。特别鸣谢:某著名搜索引擎真是厉害。
1. 向sys.path中添加路径
由于需要调用的Python模块是自己编写的,在导入之前需要先添加模块所在的路径。在按照自己的想法添加好路径以后,Python总是找不到需要的模块,添加路径的代码如下:
void PyTest() {
Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('D:\\test')");
PyObject* pModule = PyImport_ImportModule("a");
if (pModule) {
// do something
}
Py_Finalize();
}
上述代码在导入模块a时总是返回空指针,在网上查资料大家都说,导入模块时返回空指针一般都是路径的问题,经过检查发现原来是转义符的问题,虽然看上去已经转义了,可在Python看来相当于执行了 sys.path.append(‘D:\test’),其中’\t’被转义,导致路径不正确,你说我是不是傻。珍爱生命,用正斜线表示路径分隔符。
2. 导入numpy时失败
在导入numpy 模块时,会报告以下错误:
ImportError: cannot import name 'multiarray'
During handling of the above exception, another exception occurred:
...
ImportError:
Importing the multiarray numpy extension module failed. Most
likely you are trying to import a failed build of numpy.
If you're working with a numpy git repo, try `git clean -xdf` (removes all
files not under version control). Otherwise reinstall numpy.
Original error was: cannot import name 'multiarray'
按照他的说明好像是这个模块有问题,但直接在Python中使用却没有任何问题,后来发现导入numpy时只有在Debug模式下会失败。经过一番搜索和探索,终于在这里找到了答案,原来multiarray模块没有对应的Debug版的链接库,因此导致整个numpy 都无法导入。暂时的解决方法是在导入Python头文件的时候取消Debug宏,如
#ifdef _DEBUG
#undef _DEBUG
#include <Python.h>
#define _DEBUG
#else
#include <Python.h>
#endif
3. 导入tensorflow时失败
在导入tensorflow时发生下面的错误
Traceback (most recent call last):
File "<string>", line 1, in <module>
...
from tensorflow.python import *
...
prog = _os.path.basename(_sys.argv[0])
AttributeError: module 'sys' has no attribute 'argv'
这个错误是因为tensorflow需要sys.argv中的参数,但在C++中调用Python的时候没有设置设个参数,因此帮它添加上才行。这个错误真把我搞蒙了,解决方法如下:
void PyTest() {
Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.argv = ['']");
PyObject* pModule = PyImport_ImportModule("tensorflow");
if (pModule) {
// do something
}
Py_Finalize();
}
暂时先这样,以后遇到问题再加。
本文由kedixa发表于个人博客,
转载请注明作者及出处。
本文链接:https://blog.kedixa.top/2017/cpp-calls-python-traps/
感谢,”导入numpy时失败”这个问题我查了两天
谢谢!!!我VS一开始DEBUG模式调用matplotlib,第二个和第三个坑都掉进去了,一搞就是几个小时。
想问下C++调用python的时候有没有一种更好的方法解决sys.path的问题?