Deserialize protobuf buffer in Python from C++ wit

2019-08-17 20:23发布

问题:

I have a char *buffer which I convert to a C++ string std::string sbuffer(buffer); because I want to pass it to python.

C++ can work with:

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

I pass the buffer to python via:

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

The python file looks kinda like this:

import proto.protobuf_pb2


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

If I run the code I get the following error message:

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)

Do I make some fundamental error or how can I solve the issue? Is it the encoding of sbuffer (when I don't encode i get the error: TypeError: memoryview: a bytes-like object is required, not 'str')? Thanks in advance.

回答1:

I guess you want to pass your buffer as bytes. So instead of

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

you need

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

Also change python interface to accept one argument.

Source of py::bytes