使用go-zero微服务框架实现云监控后台(三.c语言操作cJson封装,json和结构体互转)

c语言操作cJson封装,以及json和结构体互转。如果不做封装直接操作cJSON有点儿繁琐。

所以封装下是很有必要的,使用起来简单好用多了。

这是我计划的终端状态监控服务的终端部分的模块组件。

终端应用程序定时更新状态文件,应用中跑的另一个后台服务则定时读取该状态文件并上送至后台服务。以此无耦合的实现对终端的状态监控。参见:终端出厂后自动化运维方案_独行猫A 的沉淀、积累、总结。天天学习,好好向上...linux,Android,Vue,Go)-CSDN博客

下面是c语言读写json文件的简单封装,完成c语言结构体到json文件,json到结构体的转换。

#include "jsonopt.h"

/**
 * Function:GetArrayValueString
 * Data:2021-11-11
 * Author:yangyongzhen
 * Description: 从json中获取ArrayItem内容
 */
int GetArrayValueString(cJSON* json,int id, char* name, char* param){
    cJSON* node;
    node = cJSON_GetArrayItem(json,id);
    if(!node){
        return -1;
    }
    sprintf(param, "%s", cJSON_GetObjectItem(node, name)->valuestring);
    return 0 ;
}


/**
 * Function:GetValueString
 * Data:2021-11-11
 * Author:yangyongzhen
 * Description: 从json中读取字符串内容
 */
char* GetValueString(cJSON* json,char* name){
	cJSON* pObj = NULL;
    pObj = cJSON_GetObjectItem(json,name);
    if(pObj != NULL){
    	return pObj->valuestring;
    }else{
    	return NULL;
    }
}

/**
 * Function:GetValueInt
 * Data:2021-11-11
 * Author:yangyongzhen
 * Description: 从json中读取int类型值
 */
int GetValueInt(cJSON* json,char* name){
	cJSON* pObj = NULL;
    pObj = cJSON_GetObjectItem(json,name);
    if(pObj != NULL){
    	return pObj->valueint;
    }else{
    	return 0;
    }
}

/**
 * Function:SetValueString
 * Data:2021-11-11
 * Author:yangyongzhen
 * Description: 向json中的String类型字段赋值
 */
int SetValueString(cJSON* json,char* name,char* value){
	//printf("set key:%s,val:%s\n",name,value);
	if(cJSON_GetObjectItem(json,name)->valuestring != NULL){
		cJSON_ReplaceItemInObject(json,name,cJSON_CreateString(value));
	}else{
		//cJSON_AddItemToObject(json, name, cJSON_CreateString(value));	
		cJSON_AddStringToObject(json, name, value);	 
	}
	return 0;
}

/**
 * Function:SetValueInt
 * Data:2021-11-11
 * Author:yangyongzhen
 * Description: 向json中的Int类型字段赋值
 */
int SetValueInt(cJSON* json,char* name,int value){
	cJSON* pObj = NULL;
	pObj = cJSON_GetObjectItem(json,name);
	if(pObj != NULL){
		pObj->valueint = value;
		pObj->valuedouble = value;
		return 0;
	}else{
		cJSON_AddNumberToObject(json, name, value);	
	}
	return 0;
}
/**
   * Copyright (C), 2021-2021,yangyongzhen 
   * File name:	 jsonopt.h 
   * Author:	 yangyongzhen
   * Version:	 0.1
   * Date:	                 2021-11-11 
   * Description: 	c语言的cJSON操作封装
 **/
#ifndef _JSON_OPT_H_
#define _JSON_OPT_H_

#include <string.h>

#include "cJSON.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * Function:S2J_setInt
 * Description:Struct向Json的Int类型赋值
 * */
#define S2J_setInt(json,stru,element) SetValueInt(json,#element,(stru)->element)  

/**
 * Function:S2J_setString
 * Description:Struct向Json的String类型赋值
 * */
#define S2J_setString(json,stru,element) SetValueString(json,#element,(stru)->element)  


/**
 * Function:J2S_getString
 * Description:Json向Struct中的String类型赋值
 * */
#define J2S_getString(json,stru,element) {char *item=NULL; item = GetValueString(json,#element); if(item!=NULL){strcpy((stru)->element,item);}}

/**
 * Function:J2S_getInt
 * Description:Json向Struct中的Int类型赋值
 * */
#define J2S_getInt(json,stru,element) (stru)->element = GetValueInt(json,#element)


/**
 * Function:GetArrayValueString
 * Data:2021-11-11
 * Author:yangyongzhen
 * Description: 从json中获取ArrayItem内容
 */
extern int GetArrayValueString(cJSON* json,int id, char* name, char* param);


/**
 * Function:GetValueString
 * Data:2021-11-11
 * Author:yangyongzhen
 * Description: 从json中读取字符串内容
 */
extern char* GetValueString(cJSON* json,char* name);

/**
 * Function:GetValueInt
 * Data:2021-11-11
 * Author:yangyongzhen
 * Description: 从json中读取int类型值
 */
extern int GetValueInt(cJSON* json,char* name);

/**
 * Function:SetValueString
 * Data:2021-11-11
 * Author:yangyongzhen
 * Description: 向json中的String类型字段赋值
 */
extern int SetValueString(cJSON* json,char* name,char* value);

/**
 * Function:SetValueInt
 * Data:2021-11-11
 * Author:yangyongzhen
 * Description: 向json中的Int类型字段赋值
 */
extern int SetValueInt(cJSON* json,char* name,int value);



#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif

 使用方法举例:

#include "jsonopt.h"
static cJSON* root;

PosStatus posStatus;

/**
从json文件中加载信息到结构体
*/
int LoadStatus(PosStatus *status){
	printf("LoadStatus ENTER\n");
	root = GetJsonObject(STATUS_FILE_NAME);
	char * out = cJSON_Print(root);
	printf("LoadStatus:json=%s\n",out);
    if(out == NULL){
        printf("LoadStatus error,no json data\n");
        return -1;
    }
	J2S_getString(root,status,sn);
	printf("[item] = %s\n",status->sn);
    J2S_getString(root,status,posno);
	printf("[item] = %s\n",status->posno);
	J2S_getString(root,status,city);
	printf("[item] = %s\n",status->city);
	J2S_getString(root,status,tyid);
	printf("[item] = %s\n",status->tyid);
	J2S_getString(root,status,sver);
	printf("[item] = %s\n",status->sver);
	J2S_getString(root,status,ctime);
	printf("[item] = %s\n",status->ctime);

    //item = GetValueString(root,"posno");
    //if(item != NULL){
    //    strcpy(status->posno,item);
    //    printf("[item] = %s\n",status->posno);
    //}
   
	return 0;
}

/**
结构体信息保存为json文件
*/
int SaveStatus(PosStatus status){
	char * out = NULL;
    printf("SaveStatus ENTER\n");
	if(root == NULL){
		printf("SaveStatus error\n");
		return -1;
	}
	S2J_setString(root,&status,sn);
	S2J_setString(root,&status,posno);

	S2J_setString(root,&status,tyid);
	S2J_setString(root,&status,city);

	S2J_setString(root,&status,sver);


	S2J_setInt(root,&status,unum1);
	S2J_setInt(root,&status,unum2);
	S2J_setInt(root,&status,amount);
	S2J_setInt(root,&status,count);
	S2J_setInt(root,&status,line);

	S2J_setString(root,&status,carno);
	S2J_setString(root,&status,jd);
	S2J_setString(root,&status,wd);

	S2J_setInt(root,&status,alarm);
	S2J_setInt(root,&status,pver);
	S2J_setInt(root,&status,bver);

	S2J_setString(root,&status,empid);
	S2J_setString(root,&status,rvs1);
	S2J_setString(root,&status,rvs2);

	S2J_setString(root,&status,stime);
	S2J_setString(root,&status,ctime);

	S2J_setInt(root,&status,tenant);


	//SetValueString(root,"carno",status.carno);
	//SetValueString(root,"jd",status.jd);
	//SetValueString(root,"wd",status.wd);

	printf("SaveStatus end\n");

	out = cJSON_Print(root);
	writeFile(STATUS_FILE_NAME,out);
	printf("SetStatus:json=%s\n",out);
	return 0;
}
//status.h头文件
#ifndef _STATUS_H_
#define _STATUS_H_
#include  "cJSON/cJSON.h"
//保存位置 终端状态监控文件存储位置
#define	STATUS_FILE_NAME	"../opt/status.json"
//#define	STATUS_FILE_NAME	"./status.json"

//终端设备状态信息
typedef struct _PosStatus{
	char sn[32];     //设备唯一号
    char posno[16];  //终端编号
    char city[10];   //城市代码
    char tyid[10];   //终端类型
    char sver[32];   //终端版本号
    int  unum1;      //未传记录数量--公交
    int  unum2;      //未传记录数量--三方
    char ndate[16];  //当前日期
    char ntime[16];  //当前时间
    int  amount;     //当班总额
    int  count;      //当班人数
    int  line;       //线路号
    char carno[16];  //车辆编号
    char jd[20];     //经度
    char wd[20];     //维度
    int  alarm;      //设备报警码
    char stime[16];  //开机时间
    char ctime[16];  //关机时间
    int  tenant;     //租户ID

}PosStatus;

extern PosStatus posStatus;

extern int LoadStatus(PosStatus *status);
extern int SaveStatus(PosStatus status);

extern int SetValueInt(cJSON* root,char* name,int value);
extern int SetValueString(cJSON* root,char* name,char* value);

extern char* GetValueString(cJSON* json,char* name);
extern int GetValueInt(cJSON* json,char* name);
extern cJSON* GetJsonObject(char* fileName);

extern int writeFile(char *filename,char *data);


#endif

static.c文件内容:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "status.h"


static cJSON* root;

PosStatus posStatus;

/**
从文件中读取json信息到结构体
*/
int LoadStatus(PosStatus *status){
	root = GetJsonObject(STATUS_FILE_NAME);
	char * out = cJSON_Print(root);
	printf("LoadStatus:json=%s\n",out);
    if(out == NULL){
        printf("LoadStatus error,no json data\n");
        return -1;
    }
    char * item = NULL;
    item = GetValueString(root,"sn");
    if(item != NULL){
        strcpy(status->sn,item);
        printf("[item] = %s\n",status->sn);
    }
    item = GetValueString(root,"posno");
    if(item != NULL){
        strcpy(status->posno,item);
        printf("[item] = %s\n",status->posno);
    }
    item = GetValueString(root,"city");
    if(item != NULL){
        strcpy(status->city,item);
        printf("[item] = %s\n",status->city);
    }
    item = GetValueString(root,"tyid");
    if(item != NULL){
        strcpy(status->tyid,item);
        printf("[item] = %s\n",status->tyid);
    }
    item = GetValueString(root,"sver");
    if(item != NULL){
        strcpy(status->sver,item);
        printf("[item] = %s\n",status->sver);
    }
   
	return 0;
}

/**
结构体信息写入json文件
*/
int SaveStatus(PosStatus status){
	char * out = NULL;
    printf("SaveStatus ENTER\n");
	if(root == NULL){
		printf("SaveStatus error\n");
		return -1;
	}
    SetValueString(root,"sn",status.sn);
    SetValueString(root,"posno",status.posno);
    SetValueString(root,"tyid",status.tyid);
	SetValueString(root,"city",status.city);

    SetValueString(root,"sver",status.sver);

	SetValueInt(root,"unum1",status.unum1);
    SetValueInt(root,"unum2",status.unum2);
    SetValueInt(root,"amount",status.amount);
    SetValueInt(root,"count",status.count);
    SetValueInt(root,"line",status.line);

	SetValueString(root,"carno",status.carno);
    SetValueString(root,"jd",status.jd);
    SetValueString(root,"wd",status.wd);

    SetValueInt(root,"alarm",status.alarm);
    SetValueString(root,"stime",status.stime);
    SetValueString(root,"ctime",status.ctime);

    SetValueInt(root,"tenant",status.tenant);

	out = cJSON_Print(root);
	writeFile(STATUS_FILE_NAME,out);
	printf("SetStatus:json=%s\n",out);
	return 0;
}

int writeFile(char *filename,char *data){
	FILE *fp = NULL;
 
	fp = fopen(filename,"w+");
	if(fp == NULL){
		fprintf(stderr,"open file failed\n");
		return -1;
	}
	fprintf(fp,"%s",data);
 
	if(fp != NULL){
		fclose(fp);
	}
	return 0;
}

cJSON* GetJsonObject(char* fileName){
    long len;
    char* pContent;
    int tmp;
    cJSON* json;

    FILE* fp = fopen(fileName, "rb+");
    if(!fp){
        printf("open file error\n");
        return NULL;
    }
    printf("open file success\n");
    fseek(fp,0,SEEK_END);
    len=ftell(fp);
    if(0 == len){
        printf("file len is 0\n");
        return NULL;
    }
   
    fseek(fp,0,SEEK_SET);
    pContent = (char*) malloc (sizeof(char)*len);
    tmp = fread(pContent,1,len,fp);

    fclose(fp);
    json = cJSON_Parse(pContent);
    if (!json)
    {
        free(pContent);
        return NULL;
    }
    free(pContent);
    printf("read file ok\n");
    return json;
}

//读取cJSON索引为index的结点某个key值对应的value,索引从0开始

int GetArrayValueString(cJSON* json,int id, char* name, char* param){
    cJSON* node;
    node = cJSON_GetArrayItem(json,id);
    if(!node){
        return -1;
    }
    sprintf(param, "%s", cJSON_GetObjectItem(node, name)->valuestring);
    return 0 ;
}

char* GetValueString(cJSON* json,char* name){
	cJSON* pObj = NULL;
    pObj = cJSON_GetObjectItem(json,name);
    if(pObj != NULL){
    	return pObj->valuestring;
    }else{
    	return NULL;
    }
}

int GetValueInt(cJSON* json,char* name){
	cJSON* pObj = NULL;
    pObj = cJSON_GetObjectItem(json,name);
    if(pObj != NULL){
    	return pObj->valueint;
    }else{
    	return 0;
    }
}

int SetValueString(cJSON* json,char* name,char* value){
	strcpy(cJSON_GetObjectItem(json,name)->valuestring,value);
	return 0;
}

int SetValueInt(cJSON* json,char* name,int value){
	cJSON_GetObjectItem(json,name)->valueint = value;
	cJSON_GetObjectItem(json,name)->valuedouble = value;
	return 0;
}


/*
int main(){
	printf("cjson test,read and save\n");
	LoadStatus(&posStatus);

    strcpy(posStatus.sver,"NC_B503_YYZ");
    posStatus.alarm = 6;
    posStatus.amount = 10;
    posStatus.count = 12;
    strcpy(posStatus.posno,"413101010E");

	SaveStatus(posStatus);
}
*/

生成的json文件如:

{
	"sn":	"00a0c6000023",
	"posno":"413101010E",
	"city":	"",
	"tyid":	"",
	"sver":	"NC_B503_YYZ",
	"unum1":	0,
	"unum2":	0,
	"ndate":	"2021-08-11",
	"ntime":	"17:20:30",
	"amount":	10,
	"count":	12,
	"line":	0,
	"carno":	"",
	"jd":	"",
	"wd":	"",
	"alarm":	6,
	"stime":	"",
	"ctime":	"",
	"tenant":	0
}

附带一个终端开机自启动脚本startmonitor.sh:

#!/bin/bash
fileName="/app/city_app/opt/monitor"
buzzGPIO="/sys/class/gpio/gpio15"
#enable buzzse for notifying success
function beep_notify()
{
   if [ ! -d "$buzzGPIO" ]; then
        echo 15 > /sys/class/gpio/export
   fi

   if [ -d "$buzzGPIO" ]; then
        echo "out" > "/sys/class/gpio/gpio15/direction"
        echo "1" > "/sys/class/gpio/gpio15/value"
        sleep 1
        echo "0" > "/sys/class/gpio/gpio15/value"
   fi
}

function CheckProcess()
{
  PROCESS_NUM=`ps | grep "$1" | grep -v "grep" | wc -l`
  
  return $PROCESS_NUM
}
if [ ! -f $fileName ]; then  
      echo "error!monitor file not exit!"
        exit 1
    else 
	echo "find monitor file,begin start..."
		CheckProcess qrlinux
		if [ $? -eq 0 ];then
		echo "no monitor progress find!"
		else
		echo "find monitor,..."
	    killall -9 monitor
        sleep 1
        fi 
        cd /app/city_app/opt/
	    ./monitor -monitorcfg=./monitorcfg.ini & 	
	    echo "start ok"
	    beep_notify
	    exit 0
fi

终端开机自启动服务应用的方法:

system("killall -9 monitor");
system("../opt/startmonitor.sh");

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

特立独行的猫a

您的鼓励是我的创作动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值