c++ 中的嵌入式 python 代码 - 导入 python 库时出错

Posted

技术标签:

【中文标题】c++ 中的嵌入式 python 代码 - 导入 python 库时出错【英文标题】:Embedded python code in c++ - error when importing python libraries 【发布时间】:2018-02-20 12:27:03 【问题描述】:

我正在尝试使用嵌入在 C++ 程序中的 Python 3.5 解释器来接收来自 C++ 的图像,并将其用作经过训练的 tensorflow 模型的输入。首先,我将图像转换为 numpy 数组,然后将其发送到 python。这是我的简化代码,工作正常(代码来自here):

Python 代码:

def multiply_fun(M):
    V = M*2
    print(V)

我调用上述函数的 C++ 代码:

#include <Python.h>
#include <abstract.h>
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include <ndarrayobject.h>
#include <vector>


int main()

    Py_InitializeEx(1);

    PyObject* sysPath = PySys_GetObject((char*)"path");
    PyObject* curDir = PyUnicode_FromString(".");
    PyList_Append(sysPath, curDir);
    Py_DECREF(curDir);

    PyObject* python_code = PyImport_ImportModule("python_code");
    PyObject* multiply_fun = PyObject_GetAttrString(python_code, "multiply_fun");
    Py_XDECREF(python_code);

    import_array1(-1);
    npy_intp dim[] =  5, 5 ;
    std::vector<double> buffer(5*5, 1);

    PyObject* array_2d = PyArray_SimpleNewFromData(2, dim, NPY_DOUBLE, &buffer[0]);
    PyObject* return_value1 = PyObject_CallFunction(multiply_fun, "O", array_2d);

    Py_XDECREF(return_value1);
    Py_XDECREF(array_2d);
    Py_XDECREF(multiply_fun);

    Py_Finalize();
    return 0;
 

但是,当我想使用大多数 python 库时,我得到一个错误。例如,对于这个 python 代码:

def multiply_fun(M):
    from skimage.io import imsave
    imsave('test.png', M)

我收到了这个错误:

Exception ignored in: <module 'threading' from 'C:\\Users\\Matin\\Anaconda3\\Lib\\threading.py'>
Traceback (most recent call last):
  File "C:\Users\Matin\Anaconda3\Lib\threading.py", line 1283, in _shutdown
    assert tlock.locked()
SystemError: <built-in method locked of _thread.lock object at 0x0000000002AF4418> returned a result with an error set

顺便说一句,This related discussion 帮不了我。

感谢您的帮助。

编辑 1: 通过将 from skimage.io import imsave 移动到 python 函数之外(如 cmets 中建议的 @moooeeeep),我在这一行中得到 Null:

PyObject* python_code = PyImport_ImportModule("python_code");

【问题讨论】:

相关:***.com/q/1188640/1025391 @moooeeeep 谢谢。请查看我编辑的帖子。 【参考方案1】:

问题似乎是PyImport_ImportModule在使用from package.submodule import function时无法加载某些包的子模块。已在Python/C API Reference Manual中解释:

当 name 参数包含一个点时(当它指定一个子模块时 包),fromlist 参数设置为列表 ['*'] 以便 返回值是命名模块而不是***包 包含它,否则会是这种情况。 (不幸的是,这有 当 name 实际上指定一个子包时的额外副作用 而不是子模块:包中指定的子模块 所有变量都已加载。)返回对导入模块的新引用,或返回 NULL 并在失败时设置异常。导入失败 模块不会将模块留在 sys.modules 中。

此函数始终使用绝对导入。

【讨论】:

导入 tensorflow 时出现新错误。 this 是我的新问题。

以上是关于c++ 中的嵌入式 python 代码 - 导入 python 库时出错的主要内容,如果未能解决你的问题,请参考以下文章

从boost python模块中的pyside导入类?

C++ - 使用 numpy 嵌入 Python

python - C++ 嵌入式解释器和对象

在嵌入式 Python C++ 应用程序中导入 Numpy

嵌入式 Python3 在导入本地模块时引发异常

使用 pybind11 通过预先存在的嵌入式 python 解释器公开 C++ 功能