配置信息读取代码(VS2012编译通过,使用了C++11特性)
配置文件的读取重复代码极多,且容易漏掉、出错,如下一段配置信息读取代码,可以简化编程。
主体类定义:
#ifndef _CONFIG_CONTAINER_H_ #define _CONFIG_CONTAINER_H_ #include <stdio.h> #include <stdlib.h> #include <memory.h> #include <vector> #include <string> #include <type_traits> template<unsigned int> struct UID{}; typedef union type_mask_t { struct { bool is_int_ : 1; bool is_enum_ : 1; bool is_float_ : 1; bool is_signed_ : 1; bool is_class_ : 1; }; unsigned int int_value; }type_mask; template<class TBase> class XConfigContainer { public: typedef void* (*def_func)(); typedef bool (*deep_copy)(void* dest, const void* src, unsigned int size); typedef struct tagConfigItem { unsigned int offset; unsigned int size; unsigned int type_mask_; const char* itemname; def_func default_func; deep_copy deep_copy_func; }ConfigItem; typedef struct tagConfigItemLink { ConfigItem cfg_item; struct tagConfigItemLink* lpnext; }ConfigItemLink; public: XConfigContainer() {} ~XConfigContainer() {} unsigned int init(void* user_param); unsigned int load(void* config_pesist, void* user_param); unsigned int load_detla(void* config_pesist, void* user_param); unsigned int save(void* config_pesist, void* user_param) const; unsigned int save_to_struct(void* config_struct, void* user_param) const; }; #define BEGIN_CONFIG_CONTAINER(class_name) \ class class_name : public XConfigContainer<class_name> \ { \ private: \ unsigned int first_item_; \ public: \ class_name() { \ memset(&first_item_, 0, sizeof( class_name ) - (unsigned int)(size_t)&(((class_name *)0)-> first_item_ )); \ }; \ ~class_name() {} \ static unsigned int x_config_item_count; \ static const ConfigItemLink* GetConfigItem(); \ public: \ template<int N> struct ConfigItemSeq{ static ConfigItemLink config_item_seq; }; \ private: \ typedef class_name thisClass; \ enum {__property_first_idx = __COUNTER__}; \ #define CONFIG_ITEM(type_name, item_name, get_default_func, copy_func) \ public: \ typedef type_name property_##item_name##_t; \ private: \ enum {__property_##item_name##_idx = __COUNTER__ - __property_first_idx - 1}; \ static unsigned int get_offset(UID<__property_##item_name##_idx>) {return (unsigned int)(size_t)&(((thisClass *)0)-> x_##item_name##_ );}; \ static unsigned int get_size(UID<__property_##item_name##_idx>) {return sizeof(property_##item_name##_t); }; \ static unsigned int get_type_mask(UID<__property_##item_name##_idx>) {static type_mask val = \ {std::is_integral<property_##item_name##_t>::value, \ std::is_enum<property_##item_name##_t>::value, \ std::is_floating_point<property_##item_name##_t>::value, \ std::is_signed<property_##item_name##_t>::value, \ std::is_class<property_##item_name##_t>::value }; return val.int_value; }; \ static const char* get_item_name(UID<__property_##item_name##_idx>) {return #item_name;}; \ static def_func get_default_value(UID<__property_##item_name##_idx>) {return get_default_func;}; \ static deep_copy get_deep_copy_func(UID<__property_##item_name##_idx>) {return copy_func;}; \ public: \ property_##item_name##_t& get_##item_name () {return x_##item_name##_;} \ protected: \ property_##item_name##_t x_##item_name##_; #define END_CONFIG_CONTAINER() \ private: \ enum {__property_last_idx = __COUNTER__ - __property_first_idx - 1}; \ public: \ static const unsigned int get_config_count() {return __property_last_idx;}; \ }; #define CONFIG_CONTAINER_IMPL(class_name) \ unsigned int class_name :: x_config_item_count = class_name :: __property_last_idx; \ template<int N> class_name::ConfigItemLink class_name ::ConfigItemSeq<N>::config_item_seq = { {get_offset(UID<N>() ), get_size(UID<N>() ), get_type_mask(UID<N>() ), get_item_name(UID<N>()), get_default_value(UID<N>()), get_deep_copy_func(UID<N>()) }, & ConfigItemSeq<N-1>::config_item_seq }; \ template<> class_name::ConfigItemLink class_name ::ConfigItemSeq<0>::config_item_seq = { {get_offset(UID<0>() ), get_size(UID<0>() ), get_type_mask(UID<0>() ), get_item_name(UID<0>()), get_default_value(UID<0>()), get_deep_copy_func(UID<0>()) }, 0 }; \ const class_name::ConfigItemLink* class_name ::GetConfigItem() \ { \ static class_name::ConfigItemLink* class_name##ItemArray = & ConfigItemSeq<__property_last_idx - 1>::config_item_seq; \ return class_name##ItemArray;\ } #define BEGIN_CONFIG2_CONTAINER(class_name, struct_name) \ class class_name : public struct_name, public XConfigContainer< class_name> \ { \ public: \ class_name() { \ memset((struct_name*)this, 0, sizeof( struct_name )); \ }; \ ~class_name() {} \ static unsigned int x_config_item_count; \ static const ConfigItemLink* GetConfigItem(); \ public: \ template<int N> struct ConfigItemSeq{ static ConfigItemLink config_item_seq; }; \ private: \ typedef class_name thisClass; \ typedef struct_name thisStruct; \ enum {__property_first_idx = __COUNTER__}; \ #define CONFIG2_ITEM(type_name, item_name, get_default_func, copy_func) \ public: \ typedef type_name property_##item_name##_t; \ private: \ enum {__property_##item_name##_idx = __COUNTER__ - __property_first_idx - 1}; \ static unsigned int get_offset(UID<__property_##item_name##_idx>) {return (unsigned int)(size_t)&(((thisClass *)0)-> item_name );}; \ static unsigned int get_size(UID<__property_##item_name##_idx>) {return sizeof(property_##item_name##_t); }; \ static unsigned int get_type_mask(UID<__property_##item_name##_idx>) {static type_mask val = \ {std::is_integral<property_##item_name##_t>::value, \ std::is_enum<property_##item_name##_t>::value, \ std::is_floating_point<property_##item_name##_t>::value, \ std::is_signed<property_##item_name##_t>::value, \ std::is_class<property_##item_name##_t>::value }; return val.int_value; }; \ static const char* get_item_name(UID<__property_##item_name##_idx>) {return #item_name;}; \ static def_func get_default_value(UID<__property_##item_name##_idx>) {return get_default_func;}; \ static deep_copy get_deep_copy_func(UID<__property_##item_name##_idx>) {return copy_func;}; \ public: \ property_##item_name##_t& get_##item_name () {return item_name;} \ #define END_CONFIG2_CONTAINER() \ private: \ enum {__property_last_idx = __COUNTER__ - __property_first_idx - 1}; \ public: \ static const unsigned int get_config_count() {return __property_last_idx;}; \ }; #define CONFIG2_CONTAINER_IMPL(class_name) \ unsigned int class_name :: x_config_item_count = class_name :: __property_last_idx; \ template<int N> class_name::ConfigItemLink class_name ::ConfigItemSeq<N>::config_item_seq = { {get_offset(UID<N>() ), get_size(UID<N>() ), get_type_mask(UID<N>() ), get_item_name(UID<N>()), get_default_value(UID<N>()), get_deep_copy_func(UID<N>()) }, & ConfigItemSeq<N-1>::config_item_seq }; \ template<> class_name::ConfigItemLink class_name ::ConfigItemSeq<0>::config_item_seq = { {get_offset(UID<0>() ), get_size(UID<0>() ), get_type_mask(UID<0>() ), get_item_name(UID<0>()), get_default_value(UID<0>()), get_deep_copy_func(UID<0>()) }, 0 }; \ const class_name::ConfigItemLink* class_name ::GetConfigItem() \ { \ static class_name::ConfigItemLink* class_name##ItemArray = & ConfigItemSeq<__property_last_idx - 1>::config_item_seq; \ return class_name##ItemArray;\ } #define DEFALUT_VALUE_DECL(value) []() -> void* {return (void*)(value);} template<class T1, class T2> T1 union_cast(T2 val){ union value_type{ T2 t2_val1; T1 t1_val2; } val1; val1.t2_val1 = val; return val1.t1_val2; } #define DEFALUT_VALUE_FLOAT_DECL(value) []() -> void* {return union_cast<void*>(value);} #endif
使用办法:
1.预先定义好的配置信息结构体
typedef struct config_param_t { unsigned short param_version; unsigned short aaa; float bbb; float ccc; } config_param;
2.声明相应的结构信息说明:
#include "ConfigContainer.h" BEGIN_CONFIG2_CONTAINER(ConfigParam, config_param); CONFIG2_ITEM(unsigned short, param_version, DEFALUT_VALUE_DECL(57920), NULL); CONFIG2_ITEM(unsigned short, aaa, DEFALUT_VALUE_DECL(0), NULL); CONFIG2_ITEM(float, bbb, DEFALUT_VALUE_FLOAT_DECL(0.5f), NULL); // ,默认值为0.5 CONFIG2_ITEM(float, ccc, DEFALUT_VALUE_FLOAT_DECL(0.5f), NULL); // ,默认值为0.6 END_CONFIG2_CONTAINER();
3.实现结构信息说明:
#include "config_param.h" CONFIG2_CONTAINER_IMPL(ConfigParam);
4-1.使用Ini来读取配置文件,相应代码:
#include <SimpleIni.h> #include "ConfigContainer.h" template<class T> void copy_value(unsigned char* dest, T* src, unsigned int size){ switch (size) { case sizeof(unsigned char): if (std::is_signed<T>::value) *(char*)dest = *(char*)src; else *(unsigned char*)dest = *(unsigned char*)src; return; case sizeof(unsigned short): if (std::is_signed<T>::value) *(short*)dest = *(short*)src; else *(unsigned short*)dest = *(unsigned short*)src; return; case sizeof(unsigned int): if (std::is_floating_point<T>::value){ *(float*)dest = *(float*)src; } else { if (std::is_signed<T>::value) *(int*)dest = *(int*)src; else *(unsigned int*)dest = *(unsigned int*)src; } return; } // 其他情况,使用memcpy memcpy(dest, src, size); } template<class TBase> unsigned int XConfigContainer<TBase>::init(void* user_param) { // 依次读取配置项 type_mask temp_type_mask; const ConfigItemLink* lpItem = TBase::GetConfigItem(); while(lpItem != nullptr) { temp_type_mask.int_value = lpItem->cfg_item.type_mask_; // 保存在内部变量中:如果是整数 def_func def_func_ = lpItem->cfg_item.default_func; if (temp_type_mask.is_int_) { if (temp_type_mask.is_signed_) { //signed int def_val = (signed int)((*def_func_)()); signed int signed_val = union_cast<signed int>((*def_func_)()); copy_value(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &signed_val, lpItem->cfg_item.size); } else { //unsigned int def_unsigned_val = (unsigned int)((*def_func_)()); unsigned int unsigned_val = union_cast<unsigned int>((*def_func_)()); copy_value(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &unsigned_val, lpItem->cfg_item.size); } } else if (temp_type_mask.is_float_){ // 浮点数 float float_val = union_cast<float>((*def_func_)()); copy_value(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &float_val, lpItem->cfg_item.size); } else { // 其他,默认是字符串 //char* strDef = (char*)((*def_func_)()); char* strValue = (char*)((*def_func_)()); // 如果有深度拷贝,则使用深拷贝函数 if (lpItem->cfg_item.deep_copy_func) { (*(lpItem->cfg_item.deep_copy_func))(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), strValue, lpItem->cfg_item.size); } else { copy_value(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), strValue, lpItem->cfg_item.size); } } lpItem = lpItem->lpnext; } return 0; } template<class TBase> unsigned int XConfigContainer<TBase>::load(void* config_pesist, void* user_param) { // 内部对象 CSimpleIniA * c_ini = (CSimpleIniA *)(config_pesist); if (0 == c_ini) { return 1; } // 依次读取配置项 type_mask temp_type_mask; const ConfigItemLink* lpItem = TBase::GetConfigItem(); while(lpItem != nullptr) { temp_type_mask.int_value = lpItem->cfg_item.type_mask_; // 保存在内部变量中:如果是整数 def_func def_func_ = lpItem->cfg_item.default_func; if (temp_type_mask.is_int_) { if (temp_type_mask.is_signed_) { //signed int def_val = (signed int)((*def_func_)()); signed int signed_val = (signed int)c_ini->GetLongValue((const char*)user_param, lpItem->cfg_item.itemname, union_cast<signed int>((*def_func_)())); copy_value(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &signed_val, lpItem->cfg_item.size); } else { //unsigned int def_unsigned_val = (unsigned int)((*def_func_)()); unsigned int unsigned_val = (signed int)c_ini->GetLongValue((const char*)user_param, lpItem->cfg_item.itemname, union_cast<unsigned int>((*def_func_)())); copy_value(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &unsigned_val, lpItem->cfg_item.size); } } else if (temp_type_mask.is_float_){ // 浮点数 //float def_float_val = union_cast<float>((*def_func_)()); float float_val = (float)c_ini->GetDoubleValue((const char*)user_param, lpItem->cfg_item.itemname, union_cast<float>((*def_func_)())); copy_value(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &float_val, lpItem->cfg_item.size); } else { // 其他,默认是字符串 //char* strDef = (char*)((*def_func_)()); char* strValue = (char*)c_ini->GetValue((const char*)user_param, lpItem->cfg_item.itemname, (char*)((*def_func_)())); // 如果有深度拷贝,则使用深拷贝函数 if (lpItem->cfg_item.deep_copy_func) { (*(lpItem->cfg_item.deep_copy_func))(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), strValue, lpItem->cfg_item.size); } else { copy_value(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), strValue, lpItem->cfg_item.size); } } lpItem = lpItem->lpnext; } return 0; } template<class TBase> unsigned int XConfigContainer<TBase>::load_detla(void* config_pesist, void* user_param) { // 内部对象 CSimpleIniA * c_ini = (CSimpleIniA *)(config_pesist); if (0 == c_ini) { return 1; } // 依次读取配置项 type_mask temp_type_mask; //cJSON * c_item = NULL; const ConfigItemLink* lpItem = TBase::GetConfigItem(); while(lpItem != nullptr) { temp_type_mask.int_value = lpItem->cfg_item.type_mask_; lpItem = lpItem->lpnext; } return 0; } template<class T> T read_value(unsigned char* dest, unsigned int size){ switch (size) { case sizeof(unsigned char): if (std::is_signed<T>::value) return (T)*(char*)dest; else return (T)*(unsigned char*)dest; case sizeof(unsigned short): if (std::is_signed<T>::value) return (T)*(short*)dest; else return (T)*(unsigned short*)dest; case sizeof(unsigned int): if (std::is_floating_point<T>::value){ return (T)*(float*)dest; } else { if (std::is_signed<T>::value) return (T)*(int*)dest; else return (T)*(unsigned int*)dest; } case sizeof(double): return *(T*)dest; default: return *(T*)dest; } return 0; } template<class TBase> unsigned int XConfigContainer<TBase>::save(void* config_pesist, void* user_param) const { // 内部对象 CSimpleIniA * c_ini = (CSimpleIniA *)(config_pesist); if (0 == c_ini) { return 1; } // 依次读取配置项 type_mask temp_type_mask; //cJSON * c_item = NULL; const ConfigItemLink* lpItem = TBase::GetConfigItem(); while(lpItem != nullptr) { lpItem = lpItem->lpnext; } return 0; } template<class TBase> unsigned int XConfigContainer<TBase>::save_to_struct(void* config_struct, void* user_param) const { void* algo_config = (void*)config_struct; if (0 == algo_config) { return 1; } type_mask temp_type_mask; const ConfigItemLink* lpItem = TBase::GetConfigItem(); while(lpItem != nullptr) { temp_type_mask.int_value = lpItem->cfg_item.type_mask_; if (temp_type_mask.is_int_) { if (temp_type_mask.is_signed_) { signed int def_val = *(signed int*)&(((unsigned char*)this)[lpItem->cfg_item.offset]); copy_value(&(((unsigned char*)algo_config)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size); } else { unsigned int def_val = *(unsigned int*)&(((unsigned char*)this)[lpItem->cfg_item.offset]); copy_value(&(((unsigned char*)algo_config)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size); } } else if (temp_type_mask.is_float_){ // 浮点数 float def_val = *(float*)&(((unsigned char*)this)[lpItem->cfg_item.offset]); copy_value(&(((unsigned char*)algo_config)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size); } else { // 其他,默认是字符串 const char* strDef = ((std::string*) &(((unsigned char*)this)[lpItem->cfg_item.offset]))->c_str(); // 如果有深度拷贝,则使用深拷贝函数 if (lpItem->cfg_item.deep_copy_func) { (*(lpItem->cfg_item.deep_copy_func))(&(((unsigned char*)algo_config)[lpItem->cfg_item.offset]), strDef, lpItem->cfg_item.size); } else { copy_value(&(((unsigned char*)algo_config)[lpItem->cfg_item.offset]), strDef, lpItem->cfg_item.size); } } lpItem = lpItem->lpnext; } return 0; }
4-2.如果使用Json,则是如下的转化代码:
#include "ConfigContainer.h" #include "cJSON.h" template<class T> void copy_value(unsigned char* dest, T* src, unsigned int size){ switch (size) { case sizeof(unsigned char): if (std::is_signed<T>::value) *(char*)dest = *(char*)src; else *(unsigned char*)dest = *(unsigned char*)src; return; case sizeof(unsigned short): if (std::is_signed<T>::value) *(short*)dest = *(short*)src; else *(unsigned short*)dest = *(unsigned short*)src; return; case sizeof(unsigned int): if (std::is_floating_point<T>::value){ *(float*)dest = *(float*)src; } else { if (std::is_signed<T>::value) *(int*)dest = *(int*)src; else *(unsigned int*)dest = *(unsigned int*)src; } return; } // 其他情况,使用memcpy memcpy(dest, src, size); } template<class TBase> unsigned int XConfigContainer<TBase>::load(void* config_pesist, void* user_param) { // 内部对象 cJSON * c_json = (cJSON *)(config_pesist); if (0 == c_json) { return 1; } // 依次读取配置项 type_mask temp_type_mask; cJSON * c_item = NULL; const ConfigItemLink* lpItem = TBase::GetConfigItem(); while(lpItem != nullptr) { // 从json数据中读取到内容 c_item = cJSON_GetObjectItem(c_json, lpItem->cfg_item.itemname); temp_type_mask.int_value = lpItem->cfg_item.type_mask_; if (NULL == c_item){ // 保存在内部变量中:如果是整数 def_func def_func_ = lpItem->cfg_item.default_func; if (temp_type_mask.is_int_) { if (temp_type_mask.is_signed_) { signed int def_val = (signed int)((*def_func_)()); copy_value(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size); } else { unsigned int def_val = (unsigned int)((*def_func_)()); copy_value(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size); } } else if (temp_type_mask.is_float_){ // 浮点数 float def_val = union_cast<float>((*def_func_)()); copy_value(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size); } else { // 其他,默认是字符串 char* strDef = (char*)((*def_func_)()); // 如果有深度拷贝,则使用深拷贝函数 if (lpItem->cfg_item.deep_copy_func) { (*(lpItem->cfg_item.deep_copy_func))(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), strDef, lpItem->cfg_item.size); } else { copy_value(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), strDef, lpItem->cfg_item.size); } } } else { if (temp_type_mask.is_int_) { if (temp_type_mask.is_signed_) { signed int def_val = c_item->valueint; copy_value(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size); } else { unsigned int def_val = c_item->valueint; copy_value(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size); } } else if (temp_type_mask.is_float_){ // 浮点数 float def_val = (float)(c_item->valuedouble); copy_value(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size); } else { // 其他,默认是字符串 char* strDef = c_item->valuestring; // 如果有深度拷贝,则使用深拷贝函数 if (lpItem->cfg_item.deep_copy_func) { (*(lpItem->cfg_item.deep_copy_func))(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), strDef, lpItem->cfg_item.size); } else { copy_value(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), strDef, lpItem->cfg_item.size); } } } lpItem = lpItem->lpnext; } return 0; } template<class TBase> unsigned int XConfigContainer<TBase>::load_detla(void* config_pesist, void* user_param) { // 内部对象 cJSON * c_json = (cJSON *)(config_pesist); if (0 == c_json) { return 1; } // 依次读取配置项 type_mask temp_type_mask; cJSON * c_item = NULL; const ConfigItemLink* lpItem = TBase::GetConfigItem(); while(lpItem != nullptr) { // 从json数据中读取到内容 c_item = cJSON_GetObjectItem(c_json, lpItem->cfg_item.itemname); temp_type_mask.int_value = lpItem->cfg_item.type_mask_; // 增量配置,则不考虑不存在的内容 if (NULL != c_item){ if (temp_type_mask.is_int_) { if (temp_type_mask.is_signed_) { signed int def_val = c_item->valueint; copy_value(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size); } else { unsigned int def_val = c_item->valueint; copy_value(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size); } } else if (temp_type_mask.is_float_){ // 浮点数 float def_val = (float)(c_item->valuedouble); copy_value(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size); } else { // 其他,默认是字符串 char* strDef = c_item->valuestring; // 如果有深度拷贝,则使用深拷贝函数 if (lpItem->cfg_item.deep_copy_func) { (*(lpItem->cfg_item.deep_copy_func))(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), strDef, lpItem->cfg_item.size); } else { copy_value(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), strDef, lpItem->cfg_item.size); } } } lpItem = lpItem->lpnext; } return 0; } template<class T> T read_value(unsigned char* dest, unsigned int size){ switch (size) { case sizeof(unsigned char): if (std::is_signed<T>::value) return (T)*(char*)dest; else return (T)*(unsigned char*)dest; case sizeof(unsigned short): if (std::is_signed<T>::value) return (T)*(short*)dest; else return (T)*(unsigned short*)dest; case sizeof(unsigned int): if (std::is_floating_point<T>::value){ return (T)*(float*)dest; } else { if (std::is_signed<T>::value) return (T)*(int*)dest; else return (T)*(unsigned int*)dest; } case sizeof(double): return *(T*)dest; default: return *(T*)dest; } return 0; } template<class TBase> unsigned int XConfigContainer<TBase>::save(void* config_pesist, void* user_param) const { // 内部对象 cJSON * c_json = (cJSON *)(config_pesist); if (0 == c_json) { return 1; } // 依次读取配置项 type_mask temp_type_mask; cJSON * c_item = NULL; const ConfigItemLink* lpItem = TBase::GetConfigItem(); while(lpItem != nullptr) { temp_type_mask.int_value = lpItem->cfg_item.type_mask_; if (temp_type_mask.is_int_) { // 暂时还不支持64位大整数 if (temp_type_mask.is_signed_) { cJSON_AddNumberToObject(c_json, lpItem->cfg_item.itemname, read_value<signed int>(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), lpItem->cfg_item.size)); } else { cJSON_AddNumberToObject(c_json, lpItem->cfg_item.itemname, read_value<unsigned int>(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), lpItem->cfg_item.size)); } } else if (temp_type_mask.is_float_){ // 浮点数 if (lpItem->cfg_item.size == sizeof(float)) { cJSON_AddNumberToObject(c_json, lpItem->cfg_item.itemname, read_value<float>(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), lpItem->cfg_item.size)); } else { cJSON_AddNumberToObject(c_json, lpItem->cfg_item.itemname, read_value<double>(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), lpItem->cfg_item.size)); } } else { // 其他,默认是字符串 cJSON_AddStringToObject(c_json, lpItem->cfg_item.itemname, ((std::string*)&((char*)(TBase*)this)[lpItem->cfg_item.offset]) -> c_str()); } lpItem = lpItem->lpnext; } return 0; } template<class TBase> unsigned int XConfigContainer<TBase>::save_to_struct(void* config_struct, void* user_param) const { void* algo_config = (void*)config_struct; if (0 == algo_config) { return 1; } type_mask temp_type_mask; const ConfigItemLink* lpItem = TBase::GetConfigItem(); while(lpItem != nullptr) { temp_type_mask.int_value = lpItem->cfg_item.type_mask_; if (temp_type_mask.is_int_) { if (temp_type_mask.is_signed_) { signed int def_val = *(signed int*)&(((unsigned char*)this)[lpItem->cfg_item.offset]); copy_value(&(((unsigned char*)algo_config)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size); } else { unsigned int def_val = *(unsigned int*)&(((unsigned char*)this)[lpItem->cfg_item.offset]); copy_value(&(((unsigned char*)algo_config)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size); } } else if (temp_type_mask.is_float_){ // 浮点数 float def_val = *(float*)&(((unsigned char*)this)[lpItem->cfg_item.offset]); copy_value(&(((unsigned char*)algo_config)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size); } else { // 其他,默认是字符串 const char* strDef = ((std::string*) &(((unsigned char*)this)[lpItem->cfg_item.offset]))->c_str(); // 如果有深度拷贝,则使用深拷贝函数 if (lpItem->cfg_item.deep_copy_func) { (*(lpItem->cfg_item.deep_copy_func))(&(((unsigned char*)algo_config)[lpItem->cfg_item.offset]), strDef, lpItem->cfg_item.size); } else { copy_value(&(((unsigned char*)algo_config)[lpItem->cfg_item.offset]), strDef, lpItem->cfg_item.size); } } lpItem = lpItem->lpnext; } return 0; }
5.使用时
#include "ConfigContainer_ini.h" ConfigParam x_config_param; CSimpleIniA* ini_file_stream_ptr_ = new CSimpleIniA(); if(SI_OK != ini_file_stream_ptr_->LoadFile(szConfigIni)){ return ; } x_config_param.load(ini_file_stream_ptr_, DEFAULT);