移植cjson到windows下编译
起因
在工作过程中发现需要让Lua支持json库,如果直接用lua版本的json解析器的话效率不够高,所以找了一个用C实现的json库--cjson,据说此库比lua版本的效率高10-20倍。但是cjson是一个安卓的库,所以需要将其移植到VC中进行使用。
环境配置
开发工具:VS2012
扩展库:Lua5.1 cjson2.1.0
移植步骤
- 建立工程
使用VS2012新建一个控制台工程,这个我就不在这里累述了,相信大家都会。什么?你不会?不会就去学嘛~ - 加入源码
我将所有的代码放在了整个工程的同级目录下,新建了一个thrid文件夹,并且将Lua、cjson的源码放了进去。 - 设置工程属性
因为cjson直接包含使用Lua的头文件,而我又不想对代码进行修改,所以我直接修改了工程里面的包含目录,将Lua和cjson的目录加了进去,一了百了。
修改移植代码
- 修改点一
提示inline之后应该输入"(",原因未知,估计是编译器规则不一样导致。反正去掉内联关键字对程序也没什么影响,去掉就去掉吧。😦 - 修改点二
万恶的snprintf()
函数,这个函数在Windows和Linux平台下规则、函数名都不一样,因为它不属于标准库里面。最好的办法是定义一个宏将两者使用统一起来,我这里就直接将snprintf()
修改为_snprintf()
了。 - 修改点三
isnan()
函数和isinf()
函数在windows下定义需要自己重新实现以下,照搬照抄就是了
#if defined(WIN32)
# ifndef FOUND_C99_ISXX
# undef isnan
# undef isinf
# endif
#endif
#if !defined(isnan) && !defined(HAVE_ISNAN) && !defined(HAVE_C99_ISNAN)
# define isnan(val) (0)
#endif
#if !defined(isinf) && !defined(HAVE_ISINF) && !defined(HAVE_C99_ISINF)
# define isinf(val) (0)
#endif
- 修改点四
strcasecmp()函数和strncasecmp()函数的定义直接照搬照抄下面的代码
#ifdef _MSC_VER
int strcasecmp(char *s1, char *s2);
int strncasecmp(char *s1, char *s2, register int n);
#endif
#ifdef _MSC_VER
int strcasecmp(char *s1, char *s2)
{
while (toupper((unsigned char)*s1) == toupper((unsigned char)*s2++))
if (*s1++ == ' ') return 0;
return(toupper((unsigned char)*s1) - toupper((unsigned char)*--s2));
}
int strncasecmp(char *s1, char *s2, register int n)
{
while (--n >= 0 && toupper((unsigned char)*s1) == toupper((unsigned char)*s2++))
if (*s1++ == ' ') return 0;
return(n < 0 ? 0 : toupper((unsigned char)*s1) - toupper((unsigned char)*--s2));
}
#endif
- 修改点五
提示"toupper"未定义;假设外部返回int。这个问题就比较好解决了,直接包含下头文件#include <ctype.h>
就可以了
如此操作之后,你就可以很愉快的享受cjson带来的快感了。
总结
总体来说要做好一个跨平台,具有高可移植性的代码,要做的工作还是蛮多的。这里偷懒了,先这么用着吧。:)
题外话
发现博客园支持Markdown有点问题,上面的代码排版错乱了,各位将就着看吧,实在不行就复制到本地后稍微调整下排版。