对于工程开发,一般有三种参数:外部可配置参数,固化参数,以及工程可配置参数。
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;
}