C++ boost.python 无法将 const char* 转换为 str
C++ boost.python cannot convert const char* to str
我想用 C++ 计算一些东西,return 结果为 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++。谁能告诉我如何解决错误?提前致谢!
你不能,因为 encoded_x.data()
不是 UTF-8。您可能需要 bytes
原始数据的副本:
将 <a href="https://docs.python.org/3/c-api/structures.html#c.PyObject" rel="nofollow noreferrer">PyObject</a>* <a href="https://docs.python.org/3/c-api/bytes.html#c.PyBytes_FromStringAndSize" rel="nofollow noreferrer">PyBytes_FromStringAndSize</a>(const char *<em>v</em>, Py_ssize_t <em>len</em>)
. Or you can use 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.data
和flow_img_x.total()
。
或 memoryview
不复制数据,而只是访问 std::vector
s 数据
使用 PyObject* <a href="https://docs.python.org/3/c-api/memoryview.html#c.PyMemoryView_FromMemory" rel="nofollow noreferrer">PyMemoryView_FromMemory</a>(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<char*>(reinterpret_cast<const char*>(encoded_x.data()))
并且只使用 PyBUF_READ
)
虽然在这种情况下您必须确保向量保持活动状态,但它不会创建不必要的副本。
我想用 C++ 计算一些东西,return 结果为 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++。谁能告诉我如何解决错误?提前致谢!
你不能,因为 encoded_x.data()
不是 UTF-8。您可能需要 bytes
原始数据的副本:
将 <a href="https://docs.python.org/3/c-api/structures.html#c.PyObject" rel="nofollow noreferrer">PyObject</a>* <a href="https://docs.python.org/3/c-api/bytes.html#c.PyBytes_FromStringAndSize" rel="nofollow noreferrer">PyBytes_FromStringAndSize</a>(const char *<em>v</em>, Py_ssize_t <em>len</em>)
. Or you can use 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.data
和flow_img_x.total()
。
或 memoryview
不复制数据,而只是访问 std::vector
s 数据
使用 PyObject* <a href="https://docs.python.org/3/c-api/memoryview.html#c.PyMemoryView_FromMemory" rel="nofollow noreferrer">PyMemoryView_FromMemory</a>(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<char*>(reinterpret_cast<const char*>(encoded_x.data()))
并且只使用 PyBUF_READ
)
虽然在这种情况下您必须确保向量保持活动状态,但它不会创建不必要的副本。