首页 > 代码库 > FlatBuffers idl的语法补充说明

FlatBuffers idl的语法补充说明



FlatBuffers发布出来一周多,周末便抽时间先研究下它的使用方法。Flatbuffers的idl的语法主要参考[http://google.github.io/flatbuffers/md__schemas.html ]。本文主要介绍几个它的monster.fbs没有给出说明的几个语法点和相关的注意事项。


1 comment


它的注释中介绍了”///",说明是可以生成document comment. 我写了如下fbs代码(假设文件名称还是monster.fbs):
   /// struct Vec3 {
   ///   x:float;
   ///   y:float;
   ///   z:float;
   /// }


"flatc -c monster.fbs"命令编译后,生成代码为:
/// struct Vec3 {   x:float;   y:float;   z:float; }


2 struct
struct默认的aliagnment是4Byte.

如下fbs代码(假设文件名称还是monster.fbs):
struct Vec4  {
 x : float;
 y : short;
 z : float;
 w : short;
}

"flatc -c monster.fbs"命令编译后,生成代码为:
MANUALLY_ALIGNED_STRUCT(4) Vec4 {
private:
 float x_;
 int16_t y_;
 int16_t __padding0;
 float z_;
 int16_t w_;
 int16_t __padding1;

public:

 Vec4(float x, int16_t y, float z, int16_t w)
   : x_(flatbuffers::EndianScalar(x)), y_(flatbuffers::EndianScalar(y)), __padding0(0), z_(flatbuffers::EndianScalar(z)), w_(flatbuffers::EndianScalar(w)), __padding1(0) {}
 float x() const { return flatbuffers::EndianScalar(x_); }
 int16_t y() const { return flatbuffers::EndianScalar(y_); }
 float z() const { return flatbuffers::EndianScalar(z_); }
 int16_t w() const { return flatbuffers::EndianScalar(w_); }
};
STRUCT_END(Vec4, 16);

3 original_order
FB(FlatBuffers的简称,下同)用original_order来保持fbs中table的field顺序,FB说明中说明它是用来修饰table的(”original_order (on a table)"),其实他也可以修饰struct。
如下fbs代码(假设文件名称还是monster.fbs):
struct Vec4_ (original_order) {
 x : float;
 y : short;
 z : float;
 w : short;
}

"flatc -c monster.fbs"命令编译后,生成代码为:
STRUCT_END(Vec4, 16);
MANUALLY_ALIGNED_STRUCT(4) Vec4_ {
private:
 float x_;
 int16_t y_;
 int16_t __padding0;
 float z_;
 int16_t w_;
 int16_t __padding1;
 
public:
 Vec4_(float x, int16_t y, float z, int16_t w)
   : x_(flatbuffers::EndianScalar(x)), y_(flatbuffers::EndianScalar(y)), __padding0(0), z_(flatbuffers::EndianScalar(z)), w_(flatbuffers::EndianScalar(w)), __padding1(0) {}
 
 float x() const { return flatbuffers::EndianScalar(x_); }
 int16_t y() const { return flatbuffers::EndianScalar(y_); }
 float z() const { return flatbuffers::EndianScalar(z_); }
 int16_t w() const { return flatbuffers::EndianScalar(w_); }
};
STRUCT_END(Vec4_, 16);

4 force_align
force_align这个关键字用来对struct进行align,此处我想说明FB的一个bug。
如下fbs代码(假设文件名称还是monster.fbs):
struct Vec3 (force_align : 8 ) {
 x : float;
 y : float;
 z : float;
}

"flatc -c monster.fbs"命令编译后,生成代码为:
MANUALLY_ALIGNED_STRUCT(8) Vec3 {
private:
 float x_;
 float y_;
 float z_;
 
public:
 Vec3(float x, float y, float z)
   : x_(flatbuffers::EndianScalar(x)), y_(flatbuffers::EndianScalar(y)), z_(flatbuffers::EndianScalar(z)) {}

 float x() const { return flatbuffers::EndianScalar(x_); }
 float y() const { return flatbuffers::EndianScalar(y_); }
 float z() const { return flatbuffers::EndianScalar(z_); }
};
STRUCT_END(Vec3, 12);


请注意上面最后一行代码的最后一个参数"12”,我已经说明以8Byte作为alignment,但是它给出的struct Vec3的size仍然为12,如果你使用上面的代码,g++会给出这样的错误提示"error: static assertion failed: compiler breaks packing rules”。


解决方法有三个,第一,你把这行代码注释掉。or 第二,把数字"12”手工改成"16”。or 第三,等待官方修正这个bug(目前我还不确定他们是否知道有这个bug,如果你在github上混请提交一下)。


 接着研究,遇到其他问题我回继续补充这篇blog。