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

 

细节问题可以查看: 

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 对象。

还可以参考: 【机器学习】C++调用Python3教程: https://blog.csdn.net/lpsl1882/article/details/80017297

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MachineLP

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值