簡體   English   中英

使用Boost交換python和C Numpy Array

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

我按照boost :: python :: numpy上的教程,發現numpy的ndarray和數組可以在C ++代碼中共享,我發現使用Boost python示例,我可以用C ++調用帶有參數的python函數並返回。

我的目標是提升python和python交換numpy數組值。

首先,我嘗試使用boost python將numpy數組傳遞給python代碼。 但是,我只找到了一種通過創建一個pylist而不是一個numpy數組來將pylist設置為PyList_SET_ITEM的方法。

在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;

}

在Python中

import numpy as np

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

使用此代碼,我發現將非常大的C int數組傳遞給Python非常困難。 有更有效的方法嗎?

首先,如果我可以使用np :: from_data將C ++數組轉換為ndarray然后將其轉換為PyObject,我想我可以將此對象本身傳遞給python。

其次,我想將使用PyObject_CallObject創建的PyObject(presult)轉換為np :: ndarray格式。 現在代碼只是一個例子,輸出成功。

換句話說,你知道如何轉換ndarray(C ++) - > PyObject(C ++),PyObject(numpy c ++) - > ndarray(c ++)?

我得到了答案,並在這里發布給其他人......

謝謝。

//#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