在c语言跟android打交道时,避免不了从android层传递json数据到c层,如果传来的是一个配置项,保存到c的结构体中,如果配置项中有一、两项,那一个一个解析放到结构体中也并不麻烦,问题来了,如果配置项多一些就显的代码冗余并且比较麻烦,这里总结了个小方法:
#include "cjson.h"
typedef unsigned char uint8_t
struct __cache_info {
char *site;
char *vd;
char *params;
char *url;
char *desturl_prefix;
char *headers;
} cache_info;
static bool set_cache_info(cache_info *info, const char *json_opts)
{
if (!info || !json_opts)
return false;
enum Types{ mNumber, mString };
struct mc_nodename
{
const char *name;
int type;
int offset;
};
#define OFF(x) offsetof(cache_info, x)
static const mc_nodename nodename[] = {
{ "site", mString, OFF(site) },
{ "vd", mString, OFF(vd) },
{ "params", mString, OFF(params) },
{ "url", mString, OFF(url) },
{ "desturl_prefix", mString, OFF(desturl_prefix) },
{ "headers", mString, OFF(headers) },
{ NULL, 0, 0 },
};
cJSON *root = cJSON_Parse(json_opts);
if (!root)
return false;
for (int i = 0; nodename[i].name; i++)
{
switch (nodename[i].type)
{
case mString:
{
cJSON* tmp = cJSON_GetObjectItem(root, nodename[i].name);
if (tmp && tmp->type == cJSON_String && tmp->valuestring)
{
LOGD("----- [%s]= %s\n", nodename[i].name, tmp->valuestring);
*(char**)(((uint8_t*)info) + nodename[i].offset) = strdup(tmp->valuestring);
}
break;
}
case mNumber:
{
cJSON* tmp = cJSON_GetObjectItem(root, nodename[i].name);
if (tmp && tmp->type == cJSON_Number && tmp->valuestring)
{
LOGD("----- [%s]= %d\n", nodename[i].name, tmp->valueint);
*(int*)(((uint8_t*)info) + nodename[i].offset) = tmp->valueint;
}
break;
}
}
}
cJSON_Delete(root);
return true;
}