protocol-buffers - nanopb oneof size requirements
问题描述
I came across nanopb and want to use it in my project. I'm writing code for an embedded device so memory limitations are a real concern.
My goal is to transfer data items from device to device, each data item has an 32bit identifier and an value. The value can be anything from 1 char to float to long string. I'm wondering what would be the most efficient way of declaring the messages for this type of problem.
I was thinking something like this:
message data_msg{
message data_item{
int32 id = 1;
oneof value{
int8 ival = 2;
float fval = 3;
string sval = 4;
}
}
repeated data_item;
}
But as I understood this is converted in to C union, which is the size of the largest element. Say I limit the string to 50 chars, then the union is always 50 bytes long, even if I would need 4 bytes for a float.
Have I understood this correctly or is there some other way to accomplish this?
Thanks!
解决方案
Your understanding is correct, the structure size in C will equal the size of the largest member of the oneof. However this is only the size in memory, the message size after serialization will be the minimum needed for the contents.
If the size in memory is an issue, there are several options available. The default of allocating maximum possibly needed size makes memory management easy. If you want to dynamically allocate only the needed amount of memory, you'll have to decide how you want to do it:
Using
PB_ENABLE_MALLOC
compilation option, you can use theFT_POINTER
field type for the string and other large fields. The memory will then be allocated usingmalloc()
from the system heap.With
FT_CALLBACK
, instead of allocating any memory, you'll get a callback where you can read out the string and process or store it any way you want. For example, if you wanted to write the string to SD card, you could do so without ever storing it completely in memory.
In overall system design, static allocation for maximum size required is often the easiest to test for. If the data fits once, it will always fit. If you go for dynamic allocation, you'll need to analyze more carefully what is the maximum possible memory usage needed.
推荐阅读
- tabulator - 在不过滤的情况下隐藏一行?
- javascript - 为什么在html中放置链接css,scss时给我错误
- python - 如何读取文件并将数据转换为数字?
- azure-functions - 使用 Ms graph 设置更改通知(订阅)服务后,如何从 Azure 函数应用程序在 Visual Studio 中获取通知
- onmouseover - 图像悬停,设置另一个图像
- continuous-integration - [python] CI/CD 工作流的最佳实践
- tensorflow - Tensorflow如何从大图像的小数据集中采样大量纹理
- apache-spark - com.microsoft.sqlserver.jdbc.SQLServerException:从 Apache Spark Databricks 读取 Azure SQLDB 时出错
- python - 没有 cmd 窗口的子进程调用
- c# - 如何在 ASP.NET Core API 中查看 Azure AD 生成的访问令牌?