Search code examples
pythonflatbuffers

Writing a vector of struct with flatbuffers


I have the following classes:

namespace Message;

struct BBox {
 xmin:float;
 xmax:float;
 ymin:float;
 ymax:float;
}

table msg {
  key:string;
  boxes: [BBox];
}

root_type Message;

To create the object I do something such as

b = flatbuffers.Builder(0)
msg.msgStart(b)
msg.msgAddKey(b, b.CreateString(key))

v = flatbuffers.Builder(0)
size = len(boxes)
msg.msgBoxesVector(v, size)
for elem in boxes:
    xmin, ymin, xmax, ymax = elem
    BBox.CreateBBox(v, xmin, xmax, ymin, ymax)
boxes = v.EndVector(size)
msg.msgAddBoxes(b, boxes)
obj = msg.msgEnd(b)
b.Finish(obj)

and no error is thrown

However when I try to display the results, the key is good but the size of the vector and the content is wrong

rep = msg.msg.GetRootAsmsg(bytearray(b.Output()), 0)
print rep.BoxesLength()  # give me 4 instead of 1 
for i in range(rep.BoxesLength()):
    print rep.Boxes(i).Xmin(),  rep.Boxes(i).Ymin()
    print rep.Boxes(i).Xmax(),  rep.Boxes(i).Ymax()

Solution

  • We have an open issue about the Python port not doing enough error checking: https://github.com/google/flatbuffers/issues/299

    The creation of the string and the vector should happen before msgStart. also, you should use just one Builder object (use just b, not v), since the above code refers from one buffer to another, which won't work.

    EDIT: the Python implementation now correctly signals an error when you try to nest vector/string/table generation. It still can't detect cross-buffer offsets however.