【问题标题】:Importing tensorflow when embedding python in c++ returns null在c++中嵌入python时导入tensorflow返回null
【发布时间】:2017-02-12 01:25:52
【问题描述】:

我有一个关于将 python 嵌入 C++ 应用程序的问题。设置如下:我有一个大型 C++ 应用程序,它生成一些数据(实时渲染图像)并显示它们。我还使用 tensorflow 在 python 中训练了一个神经网络,它将接受这些图像。

我的想法是嵌入 python 并将数据作为 numpy 数组发送,使用神经网络进行预测并取回另一个处理过的 numpy 数组以显示(在 C++ 中)。我在 python 端做了一些没有 tensorflow 的基本测试,以感受在 c 中嵌入 python 的感觉,它似乎有效。

但是,一旦我将“import tensorflow”放入我想要导入的任何 python 脚本中,我将从 C++ 部分的 PyImport_ImportModule 中获得一个 NULL。

例如

import numpy as np
def foo(img):
    return np.clip(img * 2.0, 0, 255).astype(np.uint8)

工作正常。但以下没有:

import numpy as np
import tensorflow as tf #this causes the fail

def foo(img):
    return np.clip(img * 2.0, 0, 255).astype(np.uint8)

在第二种情况下,我仍然在 tensorflow 的 stdout 中收到消息,它已经找到 cuda 等,但是模块导入失败。

我的设置是在 Windows 10 x64、Anaconda Python 3.5、tensorflow-0.12 和 CUDA 8 上。有人遇到过类似的问题吗?我测试过的其他模块(numpy、pil、scipy)似乎可以正常加载。

如果它看起来无法解决,我将求助于 c++ 部分和 python 之间的某种 IPC。

【问题讨论】:

    标签: python c++ tensorflow embedding


    【解决方案1】:

    我已经解决了这个问题。我需要使用 PySys_SetArgv 设置 argc 和 argv。我在导入失败后立即使用 PyErr_Occurred() 和 PyErr_Print() 发现了这个问题。

    【讨论】:

    • 对不起,我解决了。我已经发布了整个代码,其他人可能会觉得它很有用。
    【解决方案2】:

    参考:https://docs.python.org/3.5/extending/embedding.html

    main.cpp

    #include <Python.h>
    #include <iostream>
    #include <QString>
    #include <QDir>
    #include <cstring>
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
        PyObject *pName, *pModule, *pDict, *pFunc;
        PyObject *pArgs, *pValue;
        int i;
    
        if (argc < 3) {
            fprintf(stderr,"Usage: call pythonfile funcname [args]\n");
            return 1;
        }
    
        Py_SetProgramName((wchar_t*)L"test");
    
        Py_Initialize();
    
        PySys_SetArgv(argc, (wchar_t**)argv);
        PyRun_SimpleString("import tensorflow as tf\n"
                           "print(tf.__version__)\n");
    
        PyRun_SimpleString("import cv2\n"
                           "print(cv2.__version__)\n");
    
        QString qs = QDir::currentPath();
        std::wstring ws = qs.toStdWString();
        PySys_SetPath(ws.data());
        pName = PyUnicode_DecodeFSDefault(argv[1]);
        /* Error checking of pName left out */
    
        pModule = PyImport_Import(pName);
        Py_DECREF(pName);
    
        if (pModule != NULL) {
            pFunc = PyObject_GetAttrString(pModule, argv[2]);
            /* pFunc is a new reference */
    
            if (pFunc && PyCallable_Check(pFunc)) {
                pArgs = PyTuple_New(argc - 3);
                for (i = 0; i < argc - 3; ++i) {
                    pValue = PyLong_FromLong(atoi(argv[i + 3]));
                    if (!pValue) {
                        Py_DECREF(pArgs);
                        Py_DECREF(pModule);
                        fprintf(stderr, "Cannot convert argument\n");
                        return 1;
                    }
                    /* pValue reference stolen here: */
                    PyTuple_SetItem(pArgs, i, pValue);
                }
                pValue = PyObject_CallObject(pFunc, pArgs);
                Py_DECREF(pArgs);
                if (pValue != NULL) {
                    printf("Result of call: %ld\n", PyLong_AsLong(pValue));
                    Py_DECREF(pValue);
                }
                else {
                    Py_DECREF(pFunc);
                    Py_DECREF(pModule);
                    PyErr_Print();
                    fprintf(stderr,"Call failed\n");
                    return 1;
                }
            }
            else {
                if (PyErr_Occurred())
                    PyErr_Print();
                fprintf(stderr, "Cannot find function \"%s\"\n", argv[2]);
            }
            Py_XDECREF(pFunc);
            Py_DECREF(pModule);
        }
        else {
            PyErr_Print();
            fprintf(stderr, "Failed to load \"%s\"\n", argv[1]);
            return 1;
        }
        Py_Finalize();
        return 0;
    }
    

    乘法.py

    import tensorflow as tf
    import cv2
    
    def multiply(a,b):
        print(tf.__version__) 
        print(cv2.__version__) 
        print("Will compute", a, "times", b)
        c = 0
        for i in range(0, a):
            c = c + b
        return c
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-28
      • 2012-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多