如何清除 C++ 中的流以供 nanoPB 协议缓冲区使用?

How do I clear a stream in C++ for a nanoPB protocol buffer to use?

我在平台 IO 的 ESP32 项目中使用 nanopb。这是一个 arduino 风格的 C++ 代码库。

我正在使用一些 protobufs 对传输数据进行编码。我已经设置了 protobufs 将在根级别使用的内存,以避免每次发送消息时都重新分配内存。

// variables to store the buffer/stream the data will render into...
uint8_t buffer[MESSAGE_BUFFER_SIZE];
pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));

// object to hold the data on its way into the encode action...
TestMessage abCounts = TestMessage_init_zero;

然后我得到了通过 protobufs(使用 nanoPB)将数据编码到这个流中的函数...

void encodeABCounts(int32_t button_a, int32_t button_b, String message)
  {

    // populate our data structure...
    abCounts.a_count = button_a;
    abCounts.b_count = button_b;
    strcpy(abCounts.message, message.c_str());

    // encode the data!
    bool status = pb_encode(&stream, TestMessage_fields, &abCounts);

    if (!status)
    {
      Serial.println("Failed to encode");
      return;
    }

    // and here's some debug code I'll discuss below....
    Serial.print("Message Length: ");
    Serial.println(stream.bytes_written);
    for (int i = 0; i < stream.bytes_written; i++)
    {
      Serial.printf("%02X", buffer[i]);
    }
    Serial.println("");
  }

好的。所以第一次发生此编码操作时,这是我在串行监视器中获得的数据...

Message Length: 14
Message: 080110001A087370656369616C41

太棒了 - 一切看起来都不错。但是我第二次调用 encodeABCounts(),第三次,第四次,我得到这个...

Message Length: 28
Message: 080110001A087370656369616C41080210001A087370656369616C41

Message Length: 42
Message: 080110001A087370656369616C41080210001A087370656369616C41080310001A087370656369616C41

Message Length: 56
Message: 080110001A087370656369616C41080210001A087370656369616C41080310001A087370656369616C41080410001A087370656369616C41

...etc

所以当新数据进入时它没有清除 buffer/stream。每次 buffer/stream 只是随着新数据的添加而变长。

如何在不重新分配内存的情况下将 stream/buffer 重置为准备好对新数据进行编码并卡在其中的状态?

谢谢!

要重置流,只需重新创建它即可。现在你有这个:

pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));

您可以通过再次分配重新创建它:

stream = pb_ostream_from_buffer(buffer, sizeof(buffer));

虽然您也可以将初始流声明移动到内部 encodeABCounts() 以便每次都创建它,但如果您没有任何特殊原因在使用后保留它。流创建非常轻量级,因为它只存储缓冲区的位置和大小。