通过python接口在cpp中调用python函数时,构建传参和解析返回值都会用到python内的变量类型和c++的变量类型之间的转换。
返回值是numpy等复杂结构的数据时,可以通过先转换为list等类型再返回,或者单独构建一个函数,获取numpy内某个位置的变量的函数。
下面几个基础类型的返回值解析:
#python
#返回一个参数
def returnInt(a,b):
return a+b
#返回两个相同类型的参数
def returnTwoInt():
return 1,2
#返回字符串
def returnString():
srt = 'hello world'
return srt
#返回list
def returnList():
para = [1, 2, 3, 4]
return 1,para.tolist()
#返回两个不同类型的参数
def returnTwo():
para = [1, 2, 3, 4]
return 1,para.tolist()
#返回矩阵
def returnMat():
img = cv2.imread('test1.bmp',cv2.IMREAD_GRAYSCALE)
return img
//调用python函数,返回的数据统一为PyObject类型,需要根据实际类型进行解析
PyObject* pReturn = PyObject_CallObject(pFunc, pArgs);
//当不需要传参时,可以将参数位置为空
PyObject* pReturn = PyObject_CallObject(pFunc,NULL);
PyObject为结构体,参数ob_type->tp_name 为数据的类型
//不同类型参数传递
PyObject* p = PyTuple_New(4);
for (int i = 0; i< 4; i++)
PyTuple_SetItem(p, i, Py_BuildValue("i", i));
PyObject* pArgs = PyTuple_New(2);
PyTuple_SetItem(pArgs, 0,Py_BuildValue ("i",1));
PyTuple_SetItem(pArgs, 0,Py_BuildValue ("O",p));
//返回为list
double temp;
int i_size = PyList_Size(pReturn);
for (int i = 0; i< i_size; ++i)
{PyArg_Parse(PyList_GetItem(pReturn, i), "d", &temp);
std::cout<< "return result is "<< (temp)<< std::endl;
}
//返回为 int 和 list 两个不同类型的参数
PyArg_Parse(PyTuple_GetItem(pReturn, 0), "d", &temp);
std::cout<< "temp is "<< (temp)<< std::endl;
PyObject* pReturnlist;
PyArg_Parse(PyTuple_GetItem(pReturn, 1), "O", &pReturnlist);
i_size = PyList_Size(pReturnli);
for (int i = 0; i< i_size; ++i)
{PyArg_Parse(PyList_GetItem(pReturnli, i), "d", &temp);
std::cout<< "return result is "<< (temp)<< std::endl;
}
//返回单独一个变量
//构建输入
PyObject* pArgs = PyTuple_New(2);
PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", 1));
PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", 1));
PyObject* pReturn2 = PyObject_CallObject(pFunc, pArgs);
//解析
int nResult1; //解析为int
PyArg_Parse(pReturn2, "i", &nResult1);
std::cout<< "add="<< nResult1<< std::endl;
double nResultd; //解析为double
PyArg_Parse(pReturn2, "d", &nResultd);
std::cout<< "add="<< nResultd<< std::endl;
//返回字符串
//解析方法1:
PyObject* repr = PyObject_Repr(pReturn);
PyObject* str = PyUnicode_AsEncodedString(repr, "utf-8", "strict");
char* result = PyBytes_AsString(str);
std::cout<< result<< std::endl;
//解析方法2:
char* pstr = NULL;
PyArg_Parse(pReturn, "s", &pstr);
std::cout<< pstr<< std::endl;
//返回多个变量
//循环解析
int nResult;
i_size = PyTuple_Size(pReturn);
for (int i = 0; i< i_size; ++i)
{PyArg_Parse(PyTuple_GetItem(pReturn, i), "i", &nResult);
std::cout<< "return result is "<< (nResult)<< std::endl;
}
//直接解析
int nResult1;
int nResult2;
PyArg_ParseTuple(pReturn,"i|i", &nResult1, &nResult2);
std::cout<< "return "<< nResult5<< ' '<< nResult6<< std::endl;
//解析二维矩阵
//获得序列长度,即行数
Py_ssize_t rsize = PyObject_Size(pReturn);
std::cout<< rsize<< std::endl;
//转换到迭代器,用于提取数据
PyObject* iter = PyObject_GetIter(pReturn5);
while (true)
{//获取矩阵的第一行
PyObject* next = PyIter_Next(iter);
if (!next) {// nothing left in the iterator
break;
}
if (!PyList_Check(next))
{// error, we were expecting a list value }
//获得当前行的数据数量
Py_ssize_t foosize = PyObject_Size(next);
std::cout<< foosize<< std::endl;
//转换到迭代器,用于获取数据
PyObject* iter2 = PyObject_GetIter(next);
while (true)
{ PyObject* next2 = PyIter_Next(iter2);
if (!next2)
break;
if (!PyFloat_Check(next2))
{// error, we were expecting a floating point value}
double foo = PyFloat_AsDouble(next2);
std::cout<< foo<< " ";
}
std::cout<< std::endl;
}
python手册,接口的使用示例等
https://docs.python.org/3/
//解析常用字段:
// b<=>char 0-255的那个char
// c<=>char 单个字符
// h<=>short int
// l<=>long int
// f<=>float
// d<=>double
// s<=>char*
// O<=>PyObject
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧