[✔️]lua-cjson 编译,在unity中使用cjson

简介: [✔️]lua-cjson 编译,在unity中使用cjson

SimpleJson解析太慢


因为项目中需要解析json,使用的是SimpleJson,不过发现当json比较大的时候,SimpleJson的性能不是太好,于是在寻找替代品,因为其他项目中使用的是lua-json,经历过项目的验证,所以就顺藤摸瓜,找到了lua-cjson官网,对应的lua-cjson-github


lua-cjosn


根据lua-cjson的描述,解析json使用的是c-json,反正都是c++,最终要在unity中使用,都需要通过dll的方式调用。


第一步就是要编译c-json,因为c-json是使用CMake,我们只需要安装CMake进行编译


cmkae -B ./build
cd build
cmake ../
make


如果你感觉敲命令行太麻烦,可以选择使用vscode进行编译:


  1. vscode打开c-json


  1. vscode安装好cmake相关的插件


  1. vscode中输入命令(Ctrl+P): cmake:configure,会自动生成build目录


  1. vscode中输入命令(Ctrl+P): cmake:build,最终就在build/Debug目录下生成相关的dll


以上整个过程在vscode中的体验还是非丝滑的,推荐推荐。


dll的位数问题


unity编辑器如果是64位的,那么导入的dll也需要是64的,怎么生成64位的dll呢?


其实只需要切换下cmake的编译器,选择64位的编译器,生成的最终dll就是64位的。

unity好像不允许64位和32位的dll共存。


unity中调用dll函数


导入dll到unity


将dll放到Asset/Plugins即可,次级目录不限,


在C#中声明dll的函数


  • c++的函数声明


CJSON_PUBLIC(const char*) cJSON_Version(void);


  • c#的函数声明


[DllImport ("cjson")]  // cjson是导入的dll名字,不用关心目录问题,换而言之,dll是不允许重名的
private static extern /*前半部分是固定的格式*/ IntPtr cJSON_Version();


我们在编写c#函数声明时,需要关心下参数和返回值,凡是c语言指针类型的,到c#中统一都是IntPtr,如果你对指针理解的非常到位,其实指针就是一个int类型的内存地址数据。


其他的基础类型,int、double、float都可以直接照搬,没有类型转换。


c#调用函数参数的类型转换


c语言函数参数类型为const char* ,对应的c#类型为IntPtr


所以在c#中调用该函数时,我们需要将c#的string转换为IntPtr。


string str = "string";
IntPtr ptr = Marshal.StringToHGlobalAnsi(str);


具体原理,仔细体会下就大致能想明白了,稍微绕了个弯弯。


c语言的结构体在c#中解析


[StructLayout(LayoutKind.Sequential)] 
public struct _CJson       
{                          
  public IntPtr next;        
  public IntPtr prev;        
  public IntPtr child;       
  public int type;           
  public IntPtr valueString; 
  public int valueint;       
  public double valuedouble; 
  public IntPtr str;         
}
IntPtr ptr;
_CJson jsonObj = (_CJson)Marshal.PtrToStructure(ptr, typeof(_CJson));


这里主要用到了StructLayout,在编写时注意内存布局的问题,我实践过程中发现有些值解析不出来。


比如这里的str是正确的,但是valuedouble始终为0,在c语言的测试例中是可以正常读取到number的值的,最后放弃了,改用其他api(cJSON_GetNumberValue)获取值。


可能是我内存布局写的有问题,这里我就不再深究了。


json解析其他的选择


后来同事反馈,rapidjson性能更加强劲,吊打cjson,因为时间问题,我就不再进行验证了。


目录
相关文章
|
7月前
|
JSON Ubuntu 开发者
ubuntu 22安装lua环境&&编译lua cjson模块
通过上述步骤,可以在 Ubuntu 22.04 系统上成功安装 Lua 环境,并使用 LuaRocks 或手动编译的方式安装 lua-cjson 模块。本文详细介绍了每一步的命令和操作,确保每一步都能顺利完成,适合需要在 Ubuntu 系统上配置 Lua 开发环境的开发者参考和使用。
667 13
编译lua5.3.5报错:libreadline.so存在多处未定义的引用
编译lua5.3.5报错:libreadline.so存在多处未定义的引用
151 0
|
Linux
LINUX下载编译lua
LINUX下载编译lua
117 0
|
Windows
Visual Studio 2015编译Lua 5.3.4遇到的坑
被坑的不浅,遇到错误:“ LNK1561:必须定义入口点”,解决方案删除再建,步骤一遍一遍操作,还是报错。如下图所示:   首先,它必须要改成DLL或者LIB(动态/静态库),如果是应用程序那必须要提供main函数的主入口。
1607 0
|
Windows
Sublime Text 3(中文)添加Lua编译环境
Sublime Text 3(中文)添加Lua编译环境 本文提供全流程,中文翻译。Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页...
1650 0
Sublime Text(2/3)编译lua
想在subLime text 3中集成编译Lua(或其他语言)功能,只需要在Tool->Build System -> New Build System中将原来的 {  "shell_cmd": "make"} 替换为下面的代码: { "cmd": ["c:/User...
1214 0
|
编译器
用VC编译lua源码,生成lua语言的解释器和编译器
用VC编译lua源码,生成lua语言的解释器和编译器 1.去网址下载源码 http://www.lua.org/download.html 2.装一个VC++,我用的是VC6.0 3.接下来我们开始编译源码,我们需要编译: 一个静态库 一个动态库 一个lua语言解释器 一个lua编译器 ...
1095 0
|
5月前
|
缓存 NoSQL 搜索推荐
【📕分布式锁通关指南 03】通过Lua脚本保证redis操作的原子性
本文介绍了如何通过Lua脚本在Redis中实现分布式锁的原子性操作,避免并发问题。首先讲解了Lua脚本的基本概念及其在Redis中的使用方法,包括通过`eval`指令执行Lua脚本和通过`script load`指令缓存脚本。接着详细展示了如何用Lua脚本实现加锁、解锁及可重入锁的功能,确保同一线程可以多次获取锁而不发生死锁。最后,通过代码示例演示了如何在实际业务中调用这些Lua脚本,确保锁操作的原子性和安全性。
279 6
【📕分布式锁通关指南 03】通过Lua脚本保证redis操作的原子性
|
5月前
|
NoSQL Redis 数据库
Redis 功能扩展 Lua 脚本 对Redis扩展 eval redis.call redis.pcall
通过本文的介绍,我们详细讲解了 Lua 脚本在 Redis 中的作用、`eval` 命令的使用方法以及 `redis.call` 和 `redis.pcall` 的区别和用法。通过合理使用 Lua 脚本,可以实现复杂的业务逻辑,确保操作的原子性,并减少网络开销,从而提高系统的性能和可靠性。
179 13