2015-11-02 1 views
3

У меня есть следующие классы:Написание вектора структуры с плоскими буферами

namespace Message;

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, который не делает достаточно erro r: https://github.com/google/flatbuffers/issues/299

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

EDIT: реализация Python теперь корректно сигнализирует об ошибке при попытке вложить вектор/строку/таблицу. Тем не менее, он все еще не может обнаружить смещения перекрестного буфера.

2

дам, что я сделал, надеясь, что это может помочь другим людям (на основе 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)