简体   繁体   English

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

[英]C++ boost.python cannot convert const char* to str

I want to calculate something in C++ and return result to python. 我想用C ++计算一些东西并将结果返回给python。 This is part of the C++ code: 这是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())

The error when running python script is: 运行python脚本时的错误是:

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

After debugging, I found that the error comes from this line: 调试后,我发现错误来自此行:

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

I'm not good at C++. 我不擅长C ++。 Could anyone tell me how to fix the error? 谁能告诉我如何解决该错误? Thanks in advance! 提前致谢!

You can't because encoded_x.data() is not UTF-8. 你不能因为encoded_x.data()不是UTF-8。 You probably want bytes for a copy of the raw data: 您可能需要bytes用于原始数据的副本:

Using PyObject * PyBytes_FromStringAndSize (const char * v , Py_ssize_t len ) . 使用PyObject * PyBytes_FromStringAndSize (const char * v , Py_ssize_t len ) Or you can use PyByteArray_FromStringAndSize for a bytearray with the same arguments. 或者你可以使用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())
)));

In this case, you can get rid of the vector and use flow_img_x.data and flow_img_x.total() directly. 在这种情况下,您可以删除向量并直接使用flow_img_x.dataflow_img_x.total()


Or a memoryview to not copy the data, but just access the std::vector s data 或者是一个不复制数据的memoryview ,只是访问std::vector的数据

Using PyObject* PyMemoryView_FromMemory (char * mem , Py_ssize_t size , int flags ) 使用PyObject* PyMemoryView_FromMemory (char * mem , Py_ssize_t size , int flags )

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

(If the vector was const, you would const_cast<char*>(reinterpret_cast<const char*>(encoded_x.data())) and only use PyBUF_READ ) (如果向量是const,则将const_cast<char*>(reinterpret_cast<const char*>(encoded_x.data())) ,仅使用PyBUF_READ

You have to make sure the vector stays alive in this case though, but it won't create an unnecessary copy. 在这种情况下,您必须确保向量仍然有效,但是不会创建不必要的副本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM