【问题标题】:FlatBuffers: Send Multiple Packet Types Using a UnionFlatBuffers:使用联合发送多种数据包类型
【发布时间】:2025-11-21 05:30:02
【问题描述】:

我将通过一个连接发送多个缓冲区类型。为简单起见,想象一下这样的架构:

namespace MyEvents;  

table EventOne  
{  
  id:uint;  
  timestamp:ulong;  
  adress:string;  
}  

table EventTwo  
{  
  id:uint;  
  timestamp:ulong; 
  strength:float;   
}  

union Events {EventOne, EventTwo}  

table EventHolder  
{  
  theEvent:Events;  
}  

root_type EventHolder;  

我为 C++ 和 C# 生成所需的文件,并根据需要将它们包含在我各自的项目中。

这是我在 C++ 中编码事件的方式 - 这里是 EventOne 类型的事件:

...  
uint32_t anId(645);  
uint64_t aTimestamp(1234567);  
string anAddress("00::00::45::56::47::e5");  

flatbuffers::FlatBufferBuilder builder;  
auto addressOffset= builder.CreateString(anAddress);  
auto eventOneOffset= MyEvents::CreateEventOne(builder, anId, aTimestamp, addressOfset);   

// Here is where I am confused - how to create the EventHolder object.  
// Original code I posted about - commented out, but has error.
//auto eventHolderOffset= MyEvents::CreateEventHolder(builder, MyEvents::Events_EventOne, eventOneOffset);  // Compile error here.  

auto eventHolderOffset= MyEvents::CreateEventHolder(builder, MyEvents::Events_EventOne, eventOneOffset.Union());  // No compile error here.  

builder.Finish(eventHolderOffset);  

// Access buffer pointer and size and send it on its way.  

请注意,我在创建 EventHolder 对象时遇到问题:我有一个类型为 FlatBuffers::Offset<:eventone> 的偏移量,但 CreateEventHolder 函数采用类型为 FlatBuffers::Offset 的偏移量。

  • 此过程(包含联合类型对象的表)是使用平面缓冲区发送多种数据包类型的正确方法吗?编辑:答案似乎是“是”
  • 我是否遗漏了 theEvent 的由内而外的编码步骤?编辑:不!效果很好。
  • 如果这个过程是正确的,我需要做什么来避免类型冲突?编辑:就像 Aardappel 所说,从 Flatbuffers encoding then decoding C++ double array + table + union returns junk 开始,我只需要将 .Union() 添加到 offset 参数中。

任何帮助将不胜感激。 FWIW,我在 C++ 中编码,并在那里进行测试解码,但通过 UDP 将数据发送到 C# 应用程序以在那里进行最终解码。为此,我对数据包进行类型测试并进行相应的解释。

更新:我找到了一个示例,发现我需要将 Union 函数添加到 CreateEventHolder 中偏移量的末尾。我现在可以走了。

【问题讨论】:

    标签: c# c++ flatbuffers


    【解决方案1】:

    尝试eventOneOffset.Union() 获取该偏移量的无类型版本。也许这没有足够好的记录。

    【讨论】:

    • 哈——刚刚在一个例子中看到了。谢谢你的插话——我希望你能过来。
    • 我应该/应该在哪里使用函数 FinishEventHolderBuffer?
    • 这是一个方便调用,您可以使用而不是 builder.Finish(),如果有文件标识符,它会自动添加文件标识符。