简体   繁体   English

使用Boost交换python和C Numpy Array

[英]Using Boost to exchange python and C Numpy Array

I followed the tutorial on boost::python::numpy, found that numpy's ndarray and array could be shared inside C ++ code, and I found that using the Boost python example, I could call a python function in C ++ with arguments and return. 我按照boost :: python :: numpy上的教程,发现numpy的ndarray和数组可以在C ++代码中共享,我发现使用Boost python示例,我可以用C ++调用带有参数的python函数并返回。

My goal is that boost python and python exchange numpy array values. 我的目标是提升python和python交换numpy数组值。

First, I tried to pass the numpy array to the python code with boost python. 首先,我尝试使用boost python将numpy数组传递给python代码。 However, I only found a way to set the pylist to PyList_SET_ITEM by creating a pylist instead of a numpy array. 但是,我只找到了一种通过创建一个pylist而不是一个numpy数组来将pylist设置为PyList_SET_ITEM的方法。

In C++ 在C ++中

//https://docs.python.org/2.0/ext/buildValue.html
PyObject *Convert_Big_Array(long arr[], int length) {
    PyObject *pylist, *item;
    pylist = PyList_New(length);
    if (pylist != NULL) 
        for (int i = 0; i < length; i++) {
            item = PyLong_FromLong(arr[i]);
            PyList_SET_ITEM(pylist, i, item);
        }
    return pylist;
}


int main() {
    long arr[5] = { 4,3,2,6,10 };
    // Python 3.x Version   
    Py_SetPythonHome(L"C:\\Users\\User\\Anaconda3");
    PyObject *pName, *pModule, *pDict, *pFunc, *pValue, *presult;
    Py_Initialize();

        return 0;
    }
    pDict = PyModule_GetDict(pModule);
    pFunc = PyDict_GetItemString(pDict, (char*)"someFunction");
    if (PyCallable_Check(pFunc)) {
        pValue = Py_BuildValue("(O)", Convert_Big_Array(arr, 5));
        PyErr_Print();
        presult = PyObject_CallObject(pFunc, pValue);
        PyErr_Print();
    }
    else {
        PyErr_Print();
        return 0;
    }
    boost::python::handle<> handle(presult);
    std::cout << std::endl << "Python ndarray :" << p::extract<char const *>(p::str(handle)) << std::endl;
    Py_DECREF(pValue);
    Py_DECREF(pModule);
    Py_DECREF(pName);
    Py_Finalize();
    return 0;

}

In Python 在Python中

import numpy as np

def someFunction(text):
    print(text)
    return np.array([1,2,3])

With this code I find it very difficult to pass a very large C int array to Python. 使用此代码,我发现将非常大的C int数组传递给Python非常困难。 Is there a more efficient way? 有更有效的方法吗?

First, if I can convert a C ++ array to ndarray using np :: from_data and then convert it to PyObject, I think I can pass this object itself to python. 首先,如果我可以使用np :: from_data将C ++数组转换为ndarray然后将其转换为PyObject,我想我可以将此对象本身传递给python。

Second, I want to convert PyObject (presult) created with PyObject_CallObject to np :: ndarray format. 其次,我想将使用PyObject_CallObject创建的PyObject(presult)转换为np :: ndarray格式。 Now the code is just an example and the output is successful. 现在代码只是一个例子,输出成功。

In other words, do you know how to convert ndarray (C ++) -> PyObject (C ++), PyObject (numpy c ++) -> ndarray (c ++)? 换句话说,你知道如何转换ndarray(C ++) - > PyObject(C ++),PyObject(numpy c ++) - > ndarray(c ++)?

I got a answer, and post Here for others... 我得到了答案,并在这里发布给其他人......

thank you. 谢谢。

//#include <Python.h>
#include <stdlib.h>
#include <boost/python/numpy.hpp>
#include <boost/python.hpp>
#include <iostream>

//
////#define BOOST_PYTHON_STATIC_LIB
//
using namespace boost::python;
namespace np = boost::python::numpy;



//https://stackoverflow.com/questions/10701514/how-to-return-numpy-array-from-boostpython/14232897#14232897
np::ndarray mywrapper() {
    std::vector<short> v;
    v.push_back(3);
    v.push_back(5);
    Py_intptr_t shape[1] = { v.size() };
    np::ndarray result = np::zeros(1, shape, np::dtype::get_builtin<short>());
    std::copy(v.begin(), v.end(), reinterpret_cast<short*>(result.get_data()));
    //std::cout <<"C++ Memory Addr : " << std::dec << &result << std::endl;
    return result;
}


//https://stackoverflow.com/questions/54904448/boost-python-nullptr-while-extracting-ndarray
int main() {
    double t_end = 7;
    long arr[5] = { 4,3,2,6,10 };
    // Python 3.x Version   
    Py_SetPythonHome(L"C:\\Users\\YangwooKim\\Anaconda3");
    //PyObject *pName, *pModule, *pDict, *pFunc, *pValue, *presult;
    Py_Initialize();
    np::initialize();

    object module = import("__main__");
    object name_space = module.attr("__dict__");
    exec_file("arbName.py", name_space, name_space);

    object MyFunc = name_space["someFunction"];
    object result;
    //for(int i=0; i<1000000; i++)
        result = MyFunc(mywrapper());
    //printf("Result is %d\n", PyLong_AsLong(presult));
    //np::ndarray py_array = np::from_object(boost::python::object(handle));
    //auto k = extract<np::ndarray>();
    //np::ndarray k = np::from_object(object);
    //np::ndarray k = p::extract<np::ndarray>(object);
    //const np::ndarray& ret = k();
    auto result_array = extract<numpy::ndarray>(result);
    const numpy::ndarray& ret = result_array();
    int input_size = ret.shape(0);
    short* input_ptr = reinterpret_cast<short*>(ret.get_data());
    //std::cout << std::endl
    //  << "Python ndarray :" << p::extract<char const *>(p::str(object)) << std::endl;
    std::cout << std::endl << "Python ndarray :" << input_size << std::endl;
    for (int i = 0; i < input_size; ++i)
        std::cout <<" " <<*(input_ptr + i) <<std::endl;
    //Py_Finalize();
    //Py_Finalize();
    return 0;

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM