C++和Python混合编程
使用场景
- C++调用Python算法,而算法是在一个循环中分步计算结果,计算过程的中间结构要在UI上实时渲染;
传回调函数的原因
- 刚开始想在线程中做运算,然后把结果放到队列,主线程去取运算结果,测试Demo可行;但是,算法中用到了Numpy和sklearn的库,这两个库在线程中运算特别耗时,无法使用,最终选择了,传入回调函数的方式;
代码
- C++
#include <iostream>
#include <Python.h>
#include <exception>
using namespace std;
static PyObject* PointInfoBack(PyObject* self, PyObject*args)
{
int nType = -1;
PyObject * myobj = NULL;
if (!PyArg_ParseTuple(args, "O", &myobj))
return nullptr;
int nSize = PyDict_Size(myobj);
std::cout << "返回字典的大小为: " << nSize << std::endl;
PyObject *pType = PyDict_GetItemString(myobj, "type");
PyArg_Parse(pType, "i", &nType);
std::cout << "Type: " << nType << std::endl;
return Py_BuildValue("i", 1);
}
static PyMethodDef HahlibMethods[] = {
{"PointsBack", PointInfoBack, METH_VARARGS, ""},
{NULL, NULL, 0, NULL}
};
static PyModuleDef HashlibModule = {
PyModuleDef_HEAD_INIT, "CppInterface", NULL, -1, HahlibMethods,
NULL, NULL, NULL, NULL
};
static PyObject *PyInitCppInterface(void)
{
return PyModule_Create(&HashlibModule);
}
int main()
{
PyImport_AppendInittab("CppInterface", &PyInitCppInterface);
Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
PyObject * pModule = PyImport_ImportModule("testcall"); //Test001:Python文件名
PyObject* pFunc = PyObject_GetAttrString(pModule, "getILoomaAddress");
/*PyObject* cons_args = PyTuple_New(1);
PyTuple_SetItem(cons_args, 0, Py_BuildValue("s", "czx"));*/
if (!pFunc || !PyCallable_Check(pFunc)) {
return 0;
}
PyObject *obj = PyObject_CallObject(pFunc, NULL);
if (!obj) {
throw exception("obj not Create!");
}
Py_Finalize();
system("pause");
return 0;
}
- Python (testcall.py)
import CppInterface
def getILoomaAddress():
print('getILoomaAddress')
ret = {"status": 1, "type": 2, "vertices": [0, 1], "normals": [0, 1]}
CppInterface.PointsBack(ret)
return ret