LuaStruct

LuaStruct提供了一种简单的对Lua数据进行打包或者序列化的方式,可以方便地进行Lua与其他语言的数据传输。ToLuaRunTime中也已经集成了该库。
LuaStruct_第1张图片
其核心API只有两个:

  • struct.pack – 用于数据打包,struct.pack(格式化字符串,需要打包的数据1,需要打包的数据2 …)
  • struct.unpack – 用于数据解包,struct.unpack(格式化字符串,需要解包的字节数组,开始解包的位置)

无论打包还是解包,使用都很简单,核心思想是:对于每个需要进行操作的数据,提供该数据类型的标识,所有标识按顺序组合在一起,成为一个格式化字符串,在打包或解包接口中,通过该格式化字符串对其后的参数进行操作。

常用标识

常用数据类型标识包括:

  • “b” – signed char
  • “B” – unsigned char
  • “h” – signed short
  • “H” – unsigned short
  • “l” – signed long
  • “L” – unsigned long
  • “T” – size_t
  • “in” – signed integer, 其中n为指定integer的字节数,比如"i4",“i8”,缺省为使用本机默认字节数
  • “In” – unsigned integer, 其他与"in"相同
  • “f” – float
  • “d” – double
  • “cn” – 指定长度的字符序列,其中n为指定的字符长度,比如"c2",“c8”,缺省为1,在打包时,需要提供 至少n个的字符,超过的部分将被丢弃。
  • “c0” – 动态长度的字符序列,在打包时,会按照给定的字符串的长度动态地的进行打包;在解包时,会以该标识的前一个标识解出的数字作为长度进行解包(具体可以看下面的例子),因此需要前一个标识必须是数字。

另外,还有一些比较特殊的标识:

  • “<” – 设置为小端模式
  • “>” – 设置为大端模式
  • " " – (空格)没什么用,会被忽略,不会影响打包后的字节数组长度
  • “x” – 没有任何意义的占位符,但会影响打包后的字节数组长度,在解包的时候会跳过
  • “!n” – 指定对其宽度,其中n为宽度,必须是2的指数,如"!4","!8"

一些例子

最简单的使用:
LuaStruct_第2张图片
LuaStruct_第3张图片
在 _str_2 的例子中,调用 unpack 接口的时候指定了开始读取的位置为 5 ,即我们希望只读取后面的两个 float 的值,因此,此时解包使用的格式化字符串只需要提供 “ff” 即可。

指定大小端以及integer长度:
LuaStruct_第4张图片
LuaStruct_第5张图片
LuaStruct_第6张图片
LuaStruct_第7张图片
通过上面例子的对比推测,在使用 “in” 解包的时候,虽然 “n” 可以指定解包时读取 int 的长度,但是在读取后转换为 int 时仍然是以 int 的实际长度对读取的字节进行截断或者补全,因此,当将两个 “i4” 打包在一起并用 “i8” 解包后,仍然得到的是单个 “i4” 的值,超过的部分被直接截断了。而将单个 “i4” 打包后使用两个 "i2"解包,会每次都按照 n = 2 进行读取,并补全为一个完整的 int,且这两个 “i2” 的顺序会受到大小端设置的影响。

"x" 和 " " 的差别:

LuaStruct_第8张图片
LuaStruct_第9张图片
在 _str_2 的例子中,虽然在打包时添加了4个 “x” 占位,且打包后的长度也变成了12,但由于解包时会跳过 “x”,因此在调用 unpack 接口时并不需要特别指定开始解包的位置,使用默认位置1即可。

”cn“ 和 “c0” 的差别:

LuaStruct_第10张图片
LuaStruct_第11张图片
在"c0"的例子中,“c0” 之前的 “i” 存放的是字符串 _test_str 的长度,在打包的时候需要手动打包进去,但是在解包的时候,这个 i 只是用来提供解包字符串的长度,并不会作为数值返回出来,因此再接收的时候不需要使用变量来接收。

你可能感兴趣的:(Lua,lua)