C++ boost.python 无法将 const char* 转换为 str

Posted

技术标签:

【中文标题】C++ boost.python 无法将 const char* 转换为 str【英文标题】:C++ boost.python cannot convert const char* to str 【发布时间】:2019-03-17 12:47:15 【问题描述】:

我想用 C++ 计算一些东西并将结果返回给 python。这是 C++ 代码的一部分:

const Mat& flow_map_x, flow_map_y;
std::vector<unchar> encoded_x, encoded_y;

flow_map_x = ...;
flow_map_y = ...;

Mat flow_img_x(flow_map_x.size(), CV_8UC1);
Mat flow_img_y(flow_map_y.size(), CV_8UC1);

encoded_x.resize(flow_img_x.total());
encoded_y.resize(flow_img_y.total());

memcpy(encoded_x.data(), flow_img_x.data, flow_img_x.total());
memcpy(encoded_y.data(), flow_img_y.data, flow_img_y.total());

bp::str tmp = bp::str((const char*) encoded_x.data())

运行python脚本时的错误是:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 0: invalid start byte

调试后发现错误来自这一行:

bp::str tmp = bp::str((const char*) encoded_x.data())

我不擅长 C++。谁能告诉我如何解决这个错误?提前致谢!

【问题讨论】:

【参考方案1】:

你不能,因为encoded_x.data() 不是 UTF-8。您可能想要 bytes 获取原始数据的副本:

使用@987654322@* @987654323@(const char *<em>v</em>, Py_ssize_t <em>len</em>)。或者,您可以使用 PyByteArray_FromStringAndSize 替换具有相同参数的 bytearray

bp::object tmp(bp::handle<>(PyBytes_FromStringAndSize(
    // Data to make `bytes` object from
    reinterpret_cast<const char*>(encoded_x.data()),
    // Amount of data to read
    static_cast<Py_ssize_t>(encoded_x.size())
)));

在这种情况下,你可以去掉向量,直接使用flow_img_x.dataflow_img_x.total()


memoryview 不复制数据,而只是访问std::vectors 数据

使用PyObject* @987654326@(char *<em>mem</em>, Py_ssize_t <em>size</em>, int <em>flags</em>)

bp::object tmp(bp::handle<>(PyMemoryView_FromMemory(
    reinterpret_cast<char*>(encoded_x.data()),
    static_cast<Py_ssize_t>(encoded_x.size()),
    PyBUF_WRITE  // Or `PyBUF_READ` i if you want a read-only view
)));

(如果向量是 const,你会 const_cast&lt;char*&gt;(reinterpret_cast&lt;const char*&gt;(encoded_x.data())) 并且只使用 PyBUF_READ

在这种情况下,您必须确保向量保持活动状态,但不会创建不必要的副本。

【讨论】:

这个答案完美解决了问题!谢谢!

以上是关于C++ boost.python 无法将 const char* 转换为 str的主要内容,如果未能解决你的问题,请参考以下文章

使用 Boost.Python 将 Python 转换为 C++ 函数

通过 Boost Python 将 Python 函数转换为 C++,用作回调

使用 boost::python 将回调从 python 传递到 c++

利用boost将C++携程python可以调用的库

boost::python - C++ 调用 Python 调用 C++

使用 Boost Python 从 c++ 类创建派生的 Python 类