我有一个关于将python嵌入到C ++应用程序中的问题。设置如下:我有一个大的C ++应用程序,它生成一些数据(实时渲染图像)并显示它们。我还使用tensorflow在python中训练了一个神经网络,它将接受这些图像。
我的想法是嵌入python并将数据作为numpy数组发送,使用神经网络预测并返回另一个已处理的numpy数组(在C ++中)。我已经在python端进行了一些没有tensorflow的基本测试,以便在c等中嵌入python,这似乎有效。
但是,一旦我将“import tensorflow”放入我要导入的任何python脚本中,我将从c ++部分的PyImport_ImportModule中获取NULL。
e.g。
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。
答案 0 :(得分:4)
我已经解决了这个问题。我需要使用PySys_SetArgv设置argc和argv。我在导入失败后立即使用PyErr_Occurred()和PyErr_Print()发现了这个问题。
答案 1 :(得分:3)
参考: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;
}
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