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

本文涉及的产品
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
简介: [✔️]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,因为时间问题,我就不再进行验证了。


目录
相关文章
编译lua5.3.5报错:libreadline.so存在多处未定义的引用
编译lua5.3.5报错:libreadline.so存在多处未定义的引用
109 0
|
Linux
LINUX下载编译lua
LINUX下载编译lua
85 0
|
Windows
Visual Studio 2015编译Lua 5.3.4遇到的坑
被坑的不浅,遇到错误:“ LNK1561:必须定义入口点”,解决方案删除再建,步骤一遍一遍操作,还是报错。如下图所示:   首先,它必须要改成DLL或者LIB(动态/静态库),如果是应用程序那必须要提供main函数的主入口。
1550 0
|
Unix C语言 Linux
Lua学习---编译生成lua和luac
众所周知,Lua是一种强大的脚本语言,并且这种语言是用C语言实现的。为什么要学习这门语言?因为它可以增强我看C语言代码的功底。 我下的Lua版本是Lua5.3,关于Lua5.3的简介如下: http://www.
2642 0
|
开发工具 Android开发 图形学
Unity编译时找不到AndroidSDK的问题 | Unable to list target platforms(转载)
原文:http://www.jianshu.com/p/fe4c334ee9fe 现象 在用 Unity 编译 Android 平台的应用时,遇到 Unable to list target platforms 的问题。
2023 0
下一篇
DataWorks