http://blog.csdn.net/kowity/article/details/7256376
上次的文章(http://blog.csdn.net/kowity/article/details/7229815)讲述了上个在 Lua 中调用 zlib 压缩、解压功能的库。其实通过使用 Lua 的 alien 库就可以直接调用外部 dll 中的函数,并不需要专门为 Lua 写一个插件。
调用 zlib 压缩、解压的代码如下(参考了 LuaJIT 的部分实现方式(http://luajit.org/ext_ffi_tutorial.html)):
- require("alien")
- local zlib = alien.load("zlib1")
- zlib.compressBound:types('long', 'long')
- zlib.compress2:types('int', 'pointer', 'pointer', 'string', 'long', 'int')
- zlib.uncompress:types('int', 'pointer', 'pointer', 'string', 'long')
- local function compress(txt)
- local n = zlib.compressBound(#txt)
- local buf = alien.buffer(n)
- local buflen = alien.buffer('0000')
- local res = zlib.compress2(buf, buflen, txt, #txt, 9)
- assert(res == 0)
- -- 返回压缩结果和压缩后的长度
- return buf, alien.toulong(buflen:topointer())
- end
- local function uncompress(comp, comp_len, n)
- local buf = alien.buffer(n)
- local buflen = alien.buffer('0000')
- local res = zlib.uncompress(buf, buflen, comp, comp_len)
- assert(res == 0)
- -- 返回解压后在缓冲区中有效的部分
- return tostr(buf, alien.toulong(buflen:topointer()))
- end
- -- 有符号数转无符号数
- function toUnsigned(num)
- local n
- if num < 0 then
- n = 256 + num
- else
- n = num
- end
- return n
- end
- function tostr(buf, len)
- local str
- for i = 1, len do
- -- Lua 把 buf 里面的数当成有符号数了,
- -- 导致读出来的有负数
- local val = toUnsigned(buf[i])
- if i == 1 then
- str = string.char(val)
- else
- str = str .. string.char(val)
- end
- end
- return str
- end
- local txt = string.rep("ab\0cd", 100)
- print("Uncompressed size: ", #txt)
- local c, c_len = compress(txt)
- print("Compressed size: ", c_len)
- local txt2 = uncompress(c, c_len, #txt)
- assert(txt2 == txt)