社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

pybd11:Python到C++数据类型转换不工作

MAXEINSTEIN • 4 年前 • 148 次点击  

问题

我试图转换一个列表列表,由一个称为C++代码内部的Python函数返回。尽管 平键11 库允许从Python数据类型到C++数据类型的转换,我尝试将Python返回的列表列表转换为 std::list 属于 STD::列表 C++的字符串,每次都失败。

代码

下面是python函数(函数返回包含字符串值的列表):

def return_sheet(self):

     """Returns the sheet in a list of lists

     """

     dataTable = []

     for r in range(self._isheet.nrows):

         datalist = []

         for c in range(self._isheet.ncols):

             datalist.append(self._isheet.cell_value(r,c))

         dataTable.append(datalist)

 return dataTable

这里我用C++调用它 平键11 :

py::list obj = _tool.attr("return_sheet")();

data = py::cast<SheetData>(obj); // This is where the problem lies, This cast crashes the program

在哪里? SheetData 是一个 typedef 为:

typedef std::list<std::list<std::string> > SheetData;

在调试过程中,我发现程序实际上在这一行崩溃:

py::object dataTable = _tool.attr("return_sheet")(); // Where _tool.attr("return_sheet")() gives an py::object which is a list of list of str

有人知道,我怎样才能成功地将python列表转换为 STD::列表 属于 STD::列表 C++的?

编辑

下面是我在C++中嵌入的Python程序文件[XListal.py]: https://pastebin.com/gARnkMTv

这里是C++代码[Maun.CPP]: https://pastebin.com/wDDUB1s4

注意:XLySalt.Py中的所有其他函数不会在C++中嵌入崩溃(只有ReTurnSeTE()函数导致崩溃。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/38210
 
148 次点击  
文章 [ 1 ]  |  最新文章 4 年前
CarlosAlbaladejo
Reply   •   1 楼
CarlosAlbaladejo    5 年前

您可以使用python/c API作为解决方案(check函数 CastToSheetData )我包括下面的完整示例:

程序.py

def return_matrix():

    dataTable = []
    for r in range(0,2):
        datalist = []

        for c in range(0,2):
            datalist.append(str(r+c))

        dataTable.append(datalist)
    return dataTable

主.cpp

#include <pybind11/embed.h>
#include <iostream>
#include <list>
#include <string>

typedef std::list<std::list<std::string> > SheetData;

namespace py = pybind11;

SheetData CastToSheetData(PyObject *obj)
{
    SheetData data;
    PyObject *iter = PyObject_GetIter(obj);

    if (!iter)
        return data;
    while (true) {
        std::list<std::string> aux_list;
        PyObject *next = PyIter_Next(iter);
        if (!next) {
            // nothing left in the iterator
            break;
        }
        PyObject *iter2 = PyObject_GetIter(next);
        if (!iter2)
            continue;
        while(true) {
            PyObject *next2 = PyIter_Next(iter2);
            if (!next2) {
                // nothing left in the iterator
                break;
            }
            PyObject* pyStrObj = PyUnicode_AsUTF8String(next2); 
            char* zStr = PyBytes_AsString(pyStrObj); 
            std::string foo(strdup(zStr));
            aux_list.push_back(foo);
            Py_DECREF(pyStrObj);
        }
        data.push_back(aux_list);
    }

    return data;
}


int main()
{
    py::scoped_interpreter guard{};
    py::module calc = py::module::import("program");
    py::object result = calc.attr("return_matrix")();

    SheetData data = CastToSheetData(result.ptr());

    for (auto l : data)
    {
        std::cout << "[ ";
        for(auto s : l)
            std::cout << s <<  " ";
        std::cout << "]" << std::endl;
    }

    return 0;
}

输出:

[ 0 1 ]
[ 1 2 ]

也许,到这里来最好的方法是做一个定制 type_caster 使用类似于 CastToSheetData公司 函数内部 load 方法