Написание вектора структуры с помощью flatbuffers

У меня есть следующие классы:

Сообщение пространства имен;

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

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

root_type Message;

Для создания объекта я делаю что-то вроде

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)

и нет ошибки

Однако, когда я пытаюсь отобразить результаты, ключ хорош, но размер вектора и содержание неверны

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

2 ответа

Решение

У нас есть открытая проблема о том, что порт Python не выполняет достаточную проверку ошибок: https://github.com/google/flatbuffers/issues/299

Создание строки и вектора должно произойти раньше msgStart, Кроме того, вы должны использовать только один объект Builder (используйте только bне v), поскольку приведенный выше код ссылается из одного буфера в другой, что не сработает.

РЕДАКТИРОВАТЬ: реализация Python теперь правильно сообщает об ошибке, когда вы пытаетесь вложить генерацию вектора / строки / таблицы. Однако он все еще не может обнаружить смещения между буферами.

Я дам то, что я сделал, надеясь, что это может помочь другим людям (основываясь на ответе Aardappel)

b = flatbuffers.Builder(0)

if boxes:
    boxesOffsets = 0
    msg.msgStartBoxesVector(b, len(boxes))
    for elem in boxes:
        xmin, ymin, xmax, ymax = elem
        BBox.CreateBBox(b, float(xmin), float(xmax), float(ymin), float(ymax))
    boxesOffsets = b.EndVector(len(boxes))

msg.msgStart(b)
msg.msgAddKey(b, b.CreateString(key))
msg.msgAddUrl(b, b.CreateString(url))
msg.msgAddCountry(b, b.CreateString(country))
msg.msgAddLimit(b, limit)

if boxes:
    msg.msgAddBoxes(b, boxesOffsets)

obj = msg.msgEnd(b)
b.Finish(obj)
Другие вопросы по тегам