使用 pybind11 从 C++ 反序列化 Python 中的 protobuf 缓冲区

Posted

技术标签:

【中文标题】使用 pybind11 从 C++ 反序列化 Python 中的 protobuf 缓冲区【英文标题】:Deserialize protobuf buffer in Python from C++ with pybind11 【发布时间】:2019-07-16 15:01:09 【问题描述】:

我有一个char *buffer,我将其转换为C++ 字符串std::string sbuffer(buffer);,因为我想将它传递给python。

C++ 可以使用:

protoObj.ParseFromArray(buffer, sbuffer.size());

我将buffer 通过:

py::scoped_interpreter python;
py::module calc = py::module::import("Calculation"); 
py::object Calculation = calc.attr("Calculation");
py::object calculation = Calculation();
calculation.attr("funcName")(sbuffer.data(), sbuffer.size());

python 文件看起来有点像这样:

import proto.protobuf_pb2


class Calculation:
    def funcName(self, sbuffer, sbuffer_size):
        protoObj = ProtoBuffClass()
        protoObj.ParseFromString(sbuffer.encode('utf-8'))

如果我运行代码,我会收到以下错误消息:

terminate called after throwing an instance of 'pybind11::error_already_set'
  what():  DecodeError: Truncated message.

At:
  /usr/local/lib/python3.6/dist-packages/google/protobuf/internal/decoder.py(721): DecodeField
  /usr/local/lib/python3.6/dist-packages/google/protobuf/internal/python_message.py(1189): InternalParse
  /usr/local/lib/python3.6/dist-packages/google/protobuf/internal/python_message.py(1132): MergeFromString
  /usr/local/lib/python3.6/dist-packages/google/protobuf/message.py(187): ParseFromString
  ./Calculation.py(31): funcName

Aborted (core dumped)

我是否犯了一些根本性的错误,或者我该如何解决这个问题?是 sbuffer 的编码吗(当我不编码时,我得到错误:TypeError: memoryview: a bytes-like object is required, not 'str')?提前致谢。

【问题讨论】:

【参考方案1】:

我猜你想将缓冲区作为bytes 传递。所以而不是

calculation.attr("funcName")(sbuffer.data(), sbuffer.size());

你需要

calculation.attr("funcName")(py::bytes(sbuffer.data(), sbuffer.size()));

同时更改 python 接口以接受一个参数。

Source of py::bytes

【讨论】:

是的,谢谢,尽管我已经从 python 端对其进行了编码,而且我对字符串的转换也应该是std::string sbuffer(buffer, buffer+buffer_size);。因为 buffer 是一个 char 指针,所以我还需要为 buffer_size 提供一个int

以上是关于使用 pybind11 从 C++ 反序列化 Python 中的 protobuf 缓冲区的主要内容,如果未能解决你的问题,请参考以下文章

返回多个 py::array 而不在 pybind11 中复制

Pybind11:从 C++ 端创建并返回 numpy 数组

使用pybind11开发python扩展库

嵌套 dict 和 pybind11

_IO_FILE 的 Pybind11 文件指针包装器

并发中的 Pybind11 并行处理问题::parallel_for