在c++中嵌入python时导入tensorflow将返回null

Importing tensorflow when embedding python in c++ returns null

本文关键字:tensorflow 导入 返回 null python c++      更新时间:2023-10-16

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

我的想法是嵌入python并将数据作为numpy数组发送,使用神经网络进行预测,然后返回另一个处理过的numpy数组进行显示(用C++)。我在python方面做了一些没有tensorflow的基本测试,以了解如何将python嵌入c等中,这似乎很有效。

然而,一旦我将"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。

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

ref: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 tfn"
"print(tf.__version__)n");
PyRun_SimpleString("import cv2n"
"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 argumentn");
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: %ldn", PyLong_AsLong(pValue));
Py_DECREF(pValue);
}
else {
Py_DECREF(pFunc);
Py_DECREF(pModule);
PyErr_Print();
fprintf(stderr,"Call failedn");
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;
}

multiply.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