美文网首页Lua点滴serverunity3D技术分享
lua 用string来进行二进制buffer操作

lua 用string来进行二进制buffer操作

作者: 圣斗士皮皮 | 来源:发表于2016-10-19 14:39 被阅读283次

buffer 作为一个连续的内存区域概念,在lua中就是string了。一是内容是内存连续的,二是可以存储任何东西。在作为二进制buffer概念去使用 string 的时候,一些地方就需要注意了。

首先,buffer 和字符串的区别在于,字符串是可见字符的,c风格的字符串后面会添加一个 \0 来作为结尾,所以在 c 向 lua传递一个 buffer 的时候,请使用 lua_pushlstring 而非 lua_pushstring, 函数声明见下:

LUA_API void  (lua_pushlstring) (lua_State *L, const char *s, size_t l);

LUA_API void  (lua_pushstring) (lua_State *L, const char *s);

而在 lua 向 c 传递buffer的时候,在c端接收的时候,请使用 lua_tolstring, 而非 lua_tostring 或 tolua_tostring(tolua中接口), 函数声明如下:

LUA_API const char     *(lua_tolstring) (lua_State *L, int idx, size_t *len);

#define lua_tostring(L,i)   lua_tolstring(L, (i), NULL)
TOLUA_API const char* tolua_tostring (lua_State* L, int narg, const char* def);

其次,在对buffer进行操作,更改内部内容的时候,因为 lua 是不支持直接操作内存的,所以可以传递给c端,有c端去更改内部内容,这样lua端的字符串内容就被改变了。

但是看过lua源码之后,发现字符串有缓存。因为在lua中字符串是不会被修改的,即没有对应的修改字符串的API。字符串的不可变性,导致lua内部基于此形成一个缓存优化,即在构造一个字符串时候,会根据对应的哈希值寻找内部缓存,如果没有则新建一个并扔到缓存中去。而上面用c直接修改字符串内存的问题在于,字符串的内存内容改变了,而其哈希值却没变,从而导致了问题,例如:

local s1 = string.rep('\0', 10)
local s2 = string.rep('\0', 10)

上述代码中,s1 和 s2 对应的哈希值是一样的,因此在创建 s2 的时候,发现缓存中有个一样的,就直接返回 s1了。假如我们在 s1 新建之后,用c端硬性的修改内容区域,那么接下来获取的s2实际上并不是全0的内容了。

诚然,可以在 c 端修改内容的时候,连带更改对应的哈希值,但是这样对于 buffer 频繁修改的物件来说,未免太多余了,而且损耗性能。只好作罢。

相关文章

  • lua 用string来进行二进制buffer操作

    buffer 作为一个连续的内存区域概念,在lua中就是string了。一是内容是内存连续的,二是可以存储任何东西...

  • 自定义Buffer之split方法

    Buffer 让 JavaScript 可以操作二进制 Buffer是Nodejs的核心组成部分,在Nodejs中...

  • 字符串

    字符串操作 Lua 提供了很多的方法来支持字符串的操作: 1 string.upper(argument):字...

  • 【JS学习】 FileReader | blob ...

    聊聊JS的二进制家族:Blob、ArrayBuffer和Buffer Blob对象和string字符串 Blob对...

  • Buffer

    Buffer结构 背景  js语言没有读取或操作二进制数据流的机制,Buffer类被引入作为Nodejs API的...

  • node js(五)

    Buffer Buffer(缓冲区)介绍JavaScript 语言没有用于读取或操作二进制数据流的机制。 Buff...

  • *Buffer.String() 和 Buffer.String

    原因: *Buffer 有方法 String(), Buffer 没有 String() 方法. fmt.Prin...

  • node 核心模块学习之Buffer

    何为 Buffer 在ES6引入 TypeArray 之前,JS没有能读取和操作二进制数据流的机制,Buffer ...

  • Nodejs Buffer

    Buffer用于存储原始数据,可以让Nodejs处理二进制数据。Nodejs中处理I/O操作就可能用到Buffer...

  • C++ 读写文件

    文件操作 文本文件 写文件 读文件 接下来我们看下用string来进行读文件 第四种是每个字符进行操作

网友评论

    本文标题:lua 用string来进行二进制buffer操作

    本文链接:https://www.haomeiwen.com/subject/rewtuttx.html