对于工程开发,一般有三种参数:外部可配置参数,固化参数,以及工程可配置参数。 1、固化的就是比如#define a 1,以后调用 xx = a,那这种就是固化。 2、工程可配置参数比如多个.h文件,然后通过define来选择哪一个文件的哪一些参数,这是工程可配置参数 3、对于外部可配置参数,目前一般是采用json、xml等文件进行配置,本文介绍自己实现的一个解析自己参数的框架
首先对于一个json文件,可能存在多级数据,本文以最高两级进行说明,示例如下:
{ "s_motor_spd":[ 100, 200, 300, 400 ], "s_motor_pid":[ [1.1, 2.3 ,4.5], [0, 3, 5] ], "cfg_name":[ "joker" ] }比如这里我这里随便写了一个json,他可能存在多种数据格式,int、float、string,如果解析按照键值一个个去解析太过于麻烦,于是我在想有没有简单,可拓展的 下面是自己实现的一个,思想:将每个解析的json参数信息保存在一个结构体中,结构体中有json类型,数据大小,以及处理方式,然后将保存着json接卸信息的结构体保存在vector中
typedef void (*usr_cp_func_t)(const void* src, void *dst, size_t size); typedef void (*usr_str_handle_func_t)(const QVector<QString>, void *dst, size_t size); enum { JSON_NULL = 0, JSON_ARR, JSON_STR, JSON_NUM_FLOAT, JSON_NUM_INT, JSON_NUM_INT8 }; typedef struct { uint8_t json_type; void* dst; size_t size; usr_cp_func_t usr_cp_func; usr_str_handle_func_t usr_str_handle_func; }app_param_info_t;dst是拷贝数据到哪里,size是数据大小 然后需要实现一个模板类函数,根据JOSN的数据类型解析不同的数据并打包到buff里面
template<class T> size_t json_num_arr_handle(QJsonArray& arr, void *dst) { T* data = (T *)dst; size_t size = 0; for (auto obj : arr) { *data++ = (T)obj.toDouble(); size += sizeof(T); } return size; }然后调用 app.usr_cp_func()拷贝获取到的数据 注意usr_cp_func根据不同的数据需要用户自己实现,默认的为直接复制
static void default_usr_cp_func(const void* src, void *dst, size_t size) { memcpy(dst, sec, size); }参数构造比较简单
static app_param_info_t& app_param_info_constructor(app_param_info_t& app_param, void* dst, uint8_t type, size_t size,\ usr_cp_func_t usr_cp_func = default_usr_cp_func, usr_str_handle_func_t usr_str_handle = nullptr) { app_param.dst = dst; app_param.json_type = type; app_param.size = size; app_param.usr_cp_func = usr_cp_func; app_param.usr_str_handle_func = usr_str_handle; return app_param; }