您的位置:首页 > 编程语言 > C语言/C++

How to pass an array from C++ to an embedded python

2017-09-08 10:13 134 查看
细节问题可以查看: 


ubuntu下C++如何调用python程序,gdb调试C++代码


下面是C++调用Python二维数组传递的问题:


#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include "Python.h"
#include "numpy/arrayobject.h"
#include<iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
Py_SetProgramName(argv[0]);
Py_Initialize();
import_array()

// Build the 2D array
PyObject *pArgs, *pReturn, *pModule, *pFunc;
PyArrayObject *np_ret, *np_arg;
const int SIZE{ 10 };
npy_intp dims[2]{SIZE, SIZE};
const int ND{ 2 };
long double(*c_arr)[SIZE]{ new long double[SIZE][SIZE] };
long double* c_out;
for (int i{}; i < SIZE; i++)
for (int j{}; j < SIZE; j++)
c_arr[i][j] = i * SIZE + j;

np_arg = reinterpret_cast<PyArrayObject*>(PyArray_SimpleNewFromData(ND, dims, NPY_LONGDOUBLE,
reinterpret_cast<void*>(c_arr)));

// Calling array_tutorial from mymodule
PyObject *pName = PyUnicode_FromString("mymodule");
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if (!pModule){
cout << "mymodule can not be imported" << endl;
Py_DECREF(np_arg);
delete[] c_arr;
return 1;
}
pFunc = PyObject_GetAttrString(pModule, "array_tutorial");
if (!pFunc || !PyCallable_Check(pFunc)){
Py_DECREF(pModule);
Py_XDECREF(pFunc);
Py_DECREF(np_arg);
delete[] c_arr;
cout << "array_tutorial is null or not callable" << endl;
return 1;
}
pArgs = PyTuple_New(1);
PyTuple_SetItem(pArgs, 0, reinterpret_cast<PyObject*>(np_arg));
pReturn = PyObject_CallObject(pFunc, pArgs);
np_ret = reinterpret_cast<PyArrayObject*>(pReturn);
if (PyArray_NDIM(np_ret) != ND - 1){ // row[0] is returned
cout << "Function returned with wrong dimension" << endl;
Py_DECREF(pFunc);
Py_DECREF(pModule);
Py_DECREF(np_arg);
Py_DECREF(np_ret);
delete[] c_arr;
return 1;
}
int len{ PyArray_SHAPE(np_ret)[0] };
c_out = reinterpret_cast<long double*>(PyArray_DATA(np_ret));
cout << "Printing output array" << endl;
for (int i{}; i < len; i++)
cout << c_out[i] << ' ';
cout << endl;

// Finalizing
Py_DECREF(pFunc);
Py_DECREF(pModule);
Py_DECREF(np_arg);
Py_DECREF(np_ret);
delete[] c_arr;
Py_Finalize();
return 0;
}
如果Python返回是一个list对象,则:


// some code omitted...
cout<<"Integer List Show:"<<endl;
PyObject *pFuncTwo     = PyDict_GetItemString(pDict, "IntegerListReturn");
PyObject *FuncTwoBack  = PyObject_CallObject (pFuncTwo, nullptr);//返回List对象

if(PyList_Check(FuncTwoBack)){ //检查是否为List对象

int SizeOfList = PyList_Size(FuncTwoBack);//List对象的大小,这里SizeOfList = 3
for(Index_i = 0; Index_i < SizeOfList; Index_i++){

PyObject *ListItem = PyList_GetItem(FuncTwoBack, Index_i);//获取List对象中的每一个元素

int NumOfItems = PyList_Size(ListItem);//List对象子元素的大小,这里NumOfItems = 3

for(Index_k = 0; Index_k < NumOfItems; Index_k++){

PyObject *Item = PyList_GetItem(ListItem, Index_k);//遍历List对象中子元素中的每个元素

cout << PyInt_AsLong(Item) <<" "; //输出元素

Py_DECREF(Item); //释放空间
}

Py_DECREF(ListItem); //释放空间
}
cout<<endl;

}else{

cout<<"Not a List"<<endl;
}
如果是一个二维的list,则:
/*Return the List which contains Numpy Array*/
PyObject *pFuncOne    = PyDict_GetItemString(pDict, "ArrayListReturn");

PyObject *FuncOneBack = PyObject_CallObject(pFuncOne, nullptr);

int Index_i = 0, Index_k = 0, Index_m = 0, Index_n = 0;
if(PyList_Check(FuncOneBack)){

int SizeOfList = PyList_Size(FuncOneBack);

for(Index_i = 0; Index_i < SizeOfList; Index_i++){

PyArrayObject *ListItem = (PyArrayObject *)PyList_GetItem(FuncOneBack, Index_i);//读取List中的PyArrayObject对象,这里需要进行强制转换。

int Rows = ListItem->dimensions[0], columns = ListItem->dimensions[1];
cout<<"The "<<Index_i<<"th Array is:"<<endl;
for(Index_m = 0; Index_m < Rows; Index_m++){

for(Index_n = 0; Index_n < columns; Index_n++){

cout<<*(double *)(ListItem->data + Index_m * ListItem->strides[0] + Index_n * ListItem->strides[1])<<" ";//访问数据,Index_m 和 Index_n 分别是数组元素的坐标,乘上相应维度的步长,即可以访问数组元素
}
cout<<endl;
}

Py_DECREF(ListItem);
}
}else{

cout<<"Not a List"<<endl;
}
c++传给Python一个数组:(第一个程序有点复杂)


double CArrays[3][3] = {{1.3, 2.4, 5.6}, {4.5, 7.8, 8.9}, {1.7, 0.4, 0.8}}; //定义一个3 X 3的数组
npy_intp Dims[2] = {3, 3}; //给定维度信息
PyObject *PyArray  = PyArray_SimpleNewFromData(2, Dims, NPY_DOUBLE, CArrays); //生成包含这个多维数组的PyObject对象,使用PyArray_SimpleNewFromData函数,第一个参数2表示维度,第二个为维度数组Dims,第三个参数指出数组的类型,第四个参数为数组
PyObject *ArgArray = PyTuple_New(1);
PyTuple_SetItem(ArgArray, 0, PyArray); //同样定义大小与Python函数参数个数一致的PyTuple对象
PyObject *pFuncFive = PyDict_GetItemString(pDict, "PassArrayFromCToPython");
PyObject_CallObject(pFuncFive, ArgArray);//调用函数,传入Numpy Array 对象。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息