lua:开源库 lua-尊龙官方平台

lua:开源库 lua-cjson 安装及使用

el/2024/3/25 16:51:49

lua:开源库 lua-cjson 安装及使用

开源库 lua-cjson 是一个简单小巧的动态库,可被 lua 脚本 require 加载。

在 lua 中通过一系列的 lua-cjson api 调用完成 lua 值与 json 值的相互转换(编码及解码)。

注:lua-cjson 要求编码格式为utf8。lua-cjson 不支持 utf-16 and utf-32。


安装:

step 1:安装 lua 环境:

上传 lua 源码 lua-5.3.5.tar.gz 到用户主目录($home)下,解压缩,获得 lua-5.3.5 目录。

修改 $home/lua-5.3.5/makefile 文件:

编译 && 安装:

cd $home/lua-5.3.5/ && make linux && make install

安装完毕:

step 2:安装 lua-cjson 库:

上传 lua-cjson 源码 lua-cjson-2.1.0.tar.gz 到用户主目录($home)下,解压缩,获得 lua-cjson-2.1.0 目录。

修改 $home/lua-cjson-2.1.0/makefile 文件:

编译 && 安装:

cd $home/lua-cjson-2.1.0/ && make && make install

安装完毕:


使用:
编码:
local cjson = require "cjson"-- 创建实例
local cjson2 = cjson.new()-- 布尔类型
local lua_bool = true
print(cjson2.encode(lua_bool))-- 数组类型
local lua_array = {1, 2, 3, 4, 5, 6}
print(cjson2.encode(lua_array))-- 数值类型
local lua_number = 6.66
print(cjson2.encode(lua_number))-- 字符串类型
local lua_string = "i am test1280"
print(cjson2.encode(lua_string))-- 对象类型
local lua_object = {["name"] = "jiang",["age"] = 24,["addr"] = "beijing",["email"] = "1569989xxxx@126.com",["tel"] = "1569989xxxx"
}
print(cjson2.encode(lua_object))

执行 lua 脚本:

lua_cpath=$home/lua/lib/lua/5.1/?.so lua lua2json.lua
解码:
local cjson = require "cjson"-- 创建实例
local cjson2 = cjson.new()-- 布尔类型
local json_bool = "false"
local lua_bool = cjson2.decode(json_bool)
print(type(lua_bool))-- 数组类型
local json_array = "[9, 8, 7, 6, 5, 4, 3, 2, 1]"
local lua_array = cjson2.decode(json_array)
print(type(lua_array))
--[[
for k, v in ipairs(lua_array) doprint("k = " .. k)print("v = " .. v)
end
--]]-- 数值类型
local json_number = "666.666"
local lua_number = cjson2.decode(json_number)
print(type(lua_number))
--[[
print(lua_number)
--]]-- 字符串类型
local json_string = "\"i am test1280\""
local lua_string = cjson2.decode(json_string)
print(type(lua_string))
--[[
print(lua_string)
--]]-- 对象类型
local json_object = "{\"name\":\"jiang\",\"addr\":\"beijing\",\"age\":24,\"tel\":\"1569989xxxx\",\"email\":\"1569989xxxx@126.com\"}"
local lua_object = cjson2.decode(json_object)
print(type(lua_object))
--[[
for k, v in pairs(lua_object) doprint("k = " .. k)print("v = " .. v)
end
--]]

执行 lua 脚本:

lua_cpath=$home/lua/lib/lua/5.1/?.so lua json2lua.lua

注:

1)lua_cpath=$home/lua/lib/lua/5.1/?.so lua

将 lua_cpath 作为环境变量传入 lua 进程环境表,以便 lua 在执行 require 函数时可以知道从哪里 dlopen 这个动态库。

当然,没必要一定写到命令行中,完全可以写到 $home/.bash_profile 中,export lua_cpath。


上面的示例代码中使用了两个 api:cjson.encode and cjson.decode。

cjson.encode 是用于编码,将 lua 值转换为 json 字符串;
cjson.decode 是用于解码,将 json 字符串转换为 lua 值;

除了这两个 api,还有以下 api 可以使用:

encode_sparse_array
encode_max_depth
decode_max_depth
encode_number_precision
encode_keep_buffer
encode_invalid_numbers
decode_invalid_numbers
new

上面的示例中也有使用到 new 接口:

cjson.new can be used to instantiate an independent copy of the lua cjson module.
the new module has a separate persistent encoding buffer, and default settings.

可以通过 new 接口创建一个 cjson 实例对象,此对象含有独立的编解码缓冲区以及独立的配置参数表。

如果多个线程同时对同一个 cjson 实例对象调用编解码操作,结果是不可预估的。

因为多个线程本质上对同时对同一编解码缓冲区进行了读写操作。

所以,不同线程应当串行操作同一个 cjson 实例对象 或 并行操作互不相同的 cjson 实例对象(不同的编解码缓冲区)。

lua cjson can support lua implementations using multiple preemptive threads within a single lua state provided the persistent encoding buffer is not shared.

this can be achieved by one of the following methods:

disabling the persistent encoding buffer with cjson.encode_keep_buffer

ensuring each thread calls cjson.encode separately (ie, treat cjson.encode as non-reentrant).

using a separate cjson module table per preemptive thread (cjson.new)

lua-cjson 提供一些 api 以修改 cjson 实例对象的参数表默认配置,来影响 cjson 实例对象在编码解码时的行为过程。

例如,可以通过 encode_max_depth 和 decode_max_depth 来更改编解码时的最大嵌套深度,等等。


关于 lua-cjson cjson.encode 序列化 lua 值的一点问题

local cjson = require "cjson"
local cjson2 = cjson.new()
local array = {}
array[1] = 1 
array[6] = 6 
array[9] = 9
print(cjson2.encode(array))

执行结果为:

[1,null,null,null,null,6,null,null,9]

当存在某 key-value 对且 key 类型不是 number 类型:

local cjson = require "cjson"
local cjson2 = cjson.new()
local array = {}
array[1] = 1
array[6] = 6
array[9] = 9
array["name"] = "test1280"  -- 注意此行
print(cjson2.encode(array))

执行结果为:

{"1":1,"9":9,"6":6,"name":"test1280"}

原因在于:

lua cjson uses a heuristic to determine whether to encode a lua table as a json array or an object.

a lua table with only positive integer keys of type number will be encoded as a json array.

all other tables will be encoded as a json object.

另外,cjson.encode 不会触发元方法:

lua cjson does not use metamethods when serialising tables.

rawget is used to iterate over lua arrays

next is used to iterate over lua objects

以及,若待转换的 lua table 中的 key 有非 number 且非 string 类型值,则转换时报错:

json object keys are always strings.

hence cjson.encode only supports table keys which are type number or string.

all other types will generate an error.

在 cjson.encode 时,由于待转换 lua table 不符合转换要求可能引发一些错误:

by default, encoding the following lua values will generate errors:

numbers incompatible with the json specification (infinity, nan)

tables nested more than 1000 levels deep

excessively sparse lua arrays

我们可以通过一些 lua-cjson 提供的 api,修改 cjson 实例对象默认参数值,使得在 encode 时行为改变:

cjson.encode_invalid_numbers

cjson.encode_max_depth

cjson.encode_sparse_array


参考文档:

1.https://www.kyne.com.au/~mark/software/lua-cjson-manual.html#encode_max_depth

代码下载:

1.https://www.kyne.com.au/~mark/software/download/lua-cjson-2.1.0.tar.gz

2.https://www.kyne.com.au/~mark/software/lua-cjson.php

3.https://github.com/mpx/lua-cjson/


http://www.ngui.cc/el/5127092.html

相关文章

lua:lua-cjson:cannot serialise table: excessively sparse array

lua:lua-cjson:cannot serialise table: excessively sparse array code: local cjson require "cjson" local cjson2 cjson.new() local array {} array[19] 19 cjson2.encode(array) 执行时异常: cannot seria…

linux:-bash: fork: retry: resource temporarily unavailable

linux:-bash: fork: retry: resource temporarily unavailable 执行命令失败,报错: 原因: 在执行命令 x 过程中有对系统内核提出资源申请,而当前用户占用的某种资源已达到系统限定上限,资源不足。 复现&a…

c/c :udp ipv4 ipv6 客户端 服务端 简例

c/c:udp ipv4 ipv6 客户端 & 服务端 简例 客户端: /*********************************************************** * * filename : client.c * last revision : revision: 1.0 * last date : date: 2018/08/08 * author …

摘要算法:md5 及 java 实现样例

摘要算法:md5及java实现样例 md5 第五代的消息摘要算法(message digest algorithm)。 md5 是一种不可逆的单向散列函数。 假设 y f(x) ,则函数 f(x) 指代 md5 函数, x 为待摘要消息(输入)&…

摘要算法:sha 及 java 实现样例

摘要算法:sha 及 java 实现样例 相关链接:摘要算法:md5及java实现样例 sha 安全散列算法(secure hash algorithm)。 sha 与 md5 类似,都是单向不可逆散列函数,用于计算消息摘要,…

java:设置 eclipse 关联 jar 包源码

java:设置 eclipse 关联 jar 包源码 在 eclipse 中进行 java 开发,当我们想要查看某类的某个方法实现时可以同时按住 ctrl 并点击方法,即可查看源码。 但通常情况下,可以直接定位查看到的是工程包括的 java 类,而找不…

摘要算法:使用 openssl 实现 md5、sha256 等

摘要算法:使用 openssl 实现 md5、sha256 等 相关链接: 摘要算法:md5 及 java实现样例 摘要算法:sha 及 java 实现样例 本文主要介绍如何使用 openssl 库实现 md5、sha256 摘要算法。 case 1:md5 #include

摘要算法:aix 5.3 使用 openssl 实现 md5 等

摘要算法:aix 5.3 使用 openssl 实现 md5 等 环境: $ uname -a aix aix68112 3 5 00f7caa94c00 查看 openssl 库: $ ll /usr/lib/*ssl* lrwxrwxrwx 1 root system 41 jul 24 2017 /usr/lib/libgsk7ssl_64.so -> /us…

c/c :gethostbyname 同主机同域名有时阻塞有时立刻错误返回

c/c:gethostbyname 同主机同域名有时阻塞有时立刻错误返回 最近项目中遇到一个很奇特的问题: 在同一主机上,gethostbyname 调用,对同一域名进行查询出现两种情况: 1.阻塞一段时间,然后失败返回ÿ…

xshell:登陆执行脚本(命令)【ssh自动多级跳转】

xshell:登陆执行脚本(命令)【ssh自动多级跳转】 使用xshell在登陆到服务器时,可以配置需要自动执行的命令。 最常用的是,我们可以使用此特性完成ssh自动多级跳转。 通常,现网生产环境是和不能通过公网直…
网站地图