pybind11:Python到C++;数据类型转换不工作 问题
我试图转换一个列表,由一个叫做C++代码的Python函数返回。虽然<强> pypyd11 < /St>Realm允许从Python数据类型转换为C++数据类型,但是我尝试将Python返回的列表列表转换为<代码> STD::列表 <代码>::C++的字符串列表/<代码>,每次都失败。 代码 以下是python函数(该函数返回包含字符串值的列表):pybind11:Python到C++;数据类型转换不工作 问题,python,c++,python-c-api,pybind11,Python,C++,Python C Api,Pybind11,我试图转换一个列表,由一个叫做C++代码的Python函数返回。虽然 pypyd11 < /St>Realm允许从Python数据类型转换为C++数据类型,但是我尝试将Python返回的列表列表转换为 STD::列表 ::C++的字符串列表/,每次都失败。 代码 以下是python函数(该函数返回包含字符串值的列表): 这里我用C++调用它,使用 PybDun11: py::list obj = _tool.attr("return_sheet")(); data = py::cast<
这里我用C++调用它,使用<强> PybDun11<强>:
py::list obj = _tool.attr("return_sheet")();
data = py::cast<SheetData>(obj); // This is where the problem lies, This cast crashes the program
在调试时,我发现程序实际上在这一行崩溃:
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::列表< /C> > <代码> STD::C++的列表< /代码>? 编辑
这里是我在C++中嵌入的Python程序文件[xListal.py]:
这里是C++代码[MUn.CPP]:
注释:XLySalt.Py中的所有其他函数不会在C++中嵌入崩溃(只有RealSurthSeTE()函数导致崩溃)
< P>可以使用Python /C API作为解决方案(检查函数<代码> CastoSoTeDATa< /COD>)。我包括以下完整示例: program.pydef 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
main.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;
}
也许,最好的方法是使用
load
方法中的CastToSheetData
函数中的代码进行自定义,您可以使用Python/CAPI作为变通方法(检查函数CastToSheetData
)。我包括以下完整示例:
program.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
main.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;
}
也许,最好的方法是使用
CastToSheetData
函数中的load
方法来定制代码,谢谢您的帮助,但是提供的解决方案不起作用。您的代码在main函数中导入模块[py::module calc=py::module::import(“程序”);]的行处崩溃。而在我的代码中,程序在从python函数“return sheet”[py::object dataTable=_tool.attr(“return_sheet”)();]获取数据的行中崩溃。你能帮我弄清楚吗?我没有崩溃。看起来,您的问题与数据类型转换无关,而是将您的Python函数嵌入到C++中。您是否可以发布完整的代码来检查如何导入模块\u tool
?您是否将我的python代码添加到与main.cpp相同文件夹中的program.py文件中?当然,我将您的python程序添加到了正确的位置。您的代码在我的计算机上运行良好。我毫无问题地打印了一份excel。我使用的是64位(我将pybind11编译为64位)。更详细地说,我将VSCode与CMake 2.8、MSVC 19.12.25835.0 64位一起使用,我的python版本是3.7和pybind11 v2.3dev0。别担心,我喜欢这样做,这是对我的帮助,但提供的解决方案不起作用。您的代码在main函数中导入模块[py::module calc=py::module::import(“程序”);]的行处崩溃。而在我的代码中,程序在从python函数“return sheet”[py::object dataTable=_tool.attr(“return_sheet”)();]获取数据的行中崩溃。你能帮我弄清楚吗?我没有崩溃。看起来,您的问题与数据类型转换无关,而是将您的Python函数嵌入到C++中。您是否可以发布完整的代码来检查如何导入模块\u tool
?您是否将我的python代码添加到与main.cpp相同文件夹中的program.py文件中?当然,我将您的python程序添加到了正确的位置。您的代码在我的计算机上运行良好。我毫无问题地打印了一份excel。我使用的是64位(我将pybind11编译为64位)。更详细地说,我将VSCode与CMake 2.8、MSVC 19.12.25835.0 64位一起使用,我的python版本是3.7和pybind11 v2.3dev0。别担心,我喜欢做这个哈哈
[ 0 1 ]
[ 1 2 ]