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

Mat*_*tin 7 c++ python python-embedding python-c-api

我试图使用嵌入在C++程序中的Python 3.5解释器从C++接收图像,并将其用作我训练的张量流模型的输入.首先,我将我的图像转换为numpy数组,然后将其发送到python.这是我的简化代码,工作正常(从这里采用的代码):

Python代码:

def multiply_fun(M):
    V = M*2
    print(V)
Run Code Online (Sandbox Code Playgroud)

调用上述函数的我的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;
} 
Run Code Online (Sandbox Code Playgroud)

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

def multiply_fun(M):
    from skimage.io import imsave
    imsave('test.png', M)
Run Code Online (Sandbox Code Playgroud)

我收到了这个错误:

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
Run Code Online (Sandbox Code Playgroud)

顺便说一句,这个相关的讨论无法帮助我.

谢谢你的帮助.

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

PyObject* python_code = PyImport_ImportModule("python_code");
Run Code Online (Sandbox Code Playgroud)

Mat*_*tin 1

问题似乎是PyImport_ImportModule在使用时无法加载某些包的子模块from package.submodule import function。Python/C API 参考手册中对此进行了解释:

\n\n
\n

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

\n\n

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

\n
\n