C++调用Python时遇到的坑

0

最近在做的东西中需要在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();
}

暂时先这样,以后遇到问题再加。

0

发表评论

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