Встроенный код Python в c ++ - ошибка при импорте библиотек Python

Я пытаюсь использовать интерпретатор Python 3.5, встроенный в программу C ++, для получения изображения из C ++ и использовать его в качестве входных данных для моей обученной модели тензорного потока. Сначала я конвертирую свое изображение в массив numpy, а затем отправляю его на python. Это мой упрощенный код, который отлично работает (коды взяты из здесь):

Код 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

Кстати, это связанное обсуждение не могло не помогите мне.

Спасибо за вашу помощь.

ИЗМЕНИТЬ 1: переместив from skimage.io import imsave за пределы функции python (как @moooeeeep, предложенное в комментариях ) Я получаю Null в этой строке:

PyObject* python_code = PyImport_ImportModule("python_code");

person Matin    schedule 12.09.2017    source источник
comment
Связанный: stackoverflow.com/q/1188640/1025391   -  person moooeeeep    schedule 12.09.2017
comment
@moooeeeep Спасибо. Пожалуйста, посмотрите мой отредактированный пост.   -  person Matin    schedule 12.09.2017


Ответы (1)


Похоже, проблема в том, что PyImport_ImportModule не может загружать подмодули некоторых пакетов при использовании from package.submodule import function. Это было объяснено в Справочном руководстве по API Python / C:

Когда аргумент name содержит точку (когда он указывает подмодуль пакета), аргумент fromlist устанавливается в список ['*'], так что возвращаемое значение - это именованный модуль, а не пакет верхнего уровня, содержащий его как иначе было бы дело. (К сожалению, это имеет дополнительный побочный эффект, когда имя фактически указывает подпакет вместо подмодуля: подмодули, указанные в переменной all пакета, загружаются.) Вернуть новую ссылку на импортированный модуль, или NULL с исключением, установленным в случае сбоя. Неудачный импорт модуля не оставляет его в sys.modules.

Эта функция всегда использует абсолютный импорт.

person Matin    schedule 13.09.2017
comment
У меня появилась новая ошибка при импорте тензорного потока. это моя новая проблема. - person Matin; 13.09.2017