外贸手表网站模板,网站权重最高是多少,emulate wordpress,在门户网站做产品单页多少钱一天概述
c/c如果在日志中查看某个结构体/类的每个变量名#xff0c;变量值信息#xff0c;只能通过printf逐个格式化#xff0c;非常繁琐#xff0c;如何做到类似protobuff转json的序列化功能呢#xff1f;该dll库先通过分析pdb文件获取结构体/类的变量名称、变量地址#…概述
c/c如果在日志中查看某个结构体/类的每个变量名变量值信息只能通过printf逐个格式化非常繁琐如何做到类似protobuff转json的序列化功能呢该dll库先通过分析pdb文件获取结构体/类的变量名称、变量地址并序列化成完整json字符串极大降低了开发者工作量。
详细
概述
通过pdb文件查找指定结构体的变量命名和变量地址将指定的结构体变量内容序列话为json格式。
实现原理
com组件查找pdb文件
使用visual studio 编译后的c/c工程在输出目录都会输出xxx.pdb文件该pdb文件中包含了工程中类型的符号文件在软件调试过程中非常重要。pdb文件格式的解析依赖com组件msdia120.dll在成功注册msdia120.dll组件后通过提供的方法对pdb文件进行解析 HRESULT hr ::CoInitialize(NULL);{CComPtrIDiaDataSource pDiaDataSource;CComPtrIDiaSession pDiaSession;CComPtrIDiaSymbol pGlobalSymbol;CComBSTR bstrFilename pdb_path;if (LoadDataFromPdb(bstrFilename, pDiaDataSource, pDiaSession, pGlobalSymbol)) {LoadAllUDTs(pGlobalSymbol);//解析所有数据类型保存在全局变量g_map_udt中LoadAllEnums(pGlobalSymbol);ret 1;}}::CoUninitialize();
对变量进行序列化 #define TCDUMP(ref_var) \tcDump(typeid(ref_var).name(), (ref_var))
通过输入变量地址通过关键字typeid获取变量类型按照不同的变量类型进行不同方式的处理比如已内置变量类型为列 if (dump_as_builtin(type, ptr, root)) {return true;} bool dump_inv_as_builtin(const std::string type, void* ptr, const Json::Value root) {static const char* buildin_signed[] {char,wchar_t,signed char,int,short,long,__int8,__int16,__int32,__int64,};static const char* buildin_unsigned[] {unsigned char,unsigned short,unsigned int,unsigned long,unsigned __int8,unsigned __int16,unsigned __int32,unsigned __int64};if (type bool) {*(bool*)ptr root.asBool();return true;}if (type float) {*(float*)ptr root.asFloat();return true;}if (type double) {*(double*)ptr root.asDouble();return true;}for (auto t : buildin_signed) {if (type t) {switch (type_size(type)){case 1:*(int8_t*)ptr root.asInt();return true;case 2:*(int16_t*)ptr root.asInt();return true;case 4:*(int32_t*)ptr root.asInt();return true;case 8:*(int64_t*)ptr root.asInt64();return true;default:return false;}}}for (auto t : buildin_unsigned) {if (type t) {switch (type_size(type)){case 1:*(uint8_t*)ptr root.asUInt();return true;case 2:*(uint16_t*)ptr root.asUInt();return true;case 4:*(uint32_t*)ptr root.asUInt();return true;case 8:*(uint64_t*)ptr root.asUInt64();return true;default:return false;}}}return false;}
demo效果
在release下执行tcdumpTest.exe 看效果
注意使用前先看‘使用说明.txt’需要先注册\DIA SDK\bin\msdia120.dll。
定义类、结构体 Class Ctest{Public:Int M_i 1;Float M_f 0.1;Double M_d 0.2;Char M_c a;Std::String M_str Hello World;Std::VectorInt M_v;Std::MapInt, Std::String M_map;};
赋值 Ctest Test;Test.M_v.Push_back(1);Test.M_v.Push_back(2);Test.M_v.Push_back(3);Test.M_map.Insert({ 1,hello });test.m_map.insert({ 2,world });
初始化tcDump并序列化对象 int ret TCDUMP_INIT(R(..\tcDumpTest.pdb));if (ret 0) {std::cout load pdb failed !!! std::endl;return 0;}// 打印 test 变量内容已json格式输出auto retJson TCDUMP(test);if (NULL retJson) {return false;}std::cout retJson std::endl;
序列化结果retJson输出 附加接口
能够通过已知结构体大小返回大小一致的结构体名称 // 打印pdb中大小为 n的类和结构体名称std::cout tcDump_GetSizeClass(sizeof(CTest)) std::endl;输出---{ CTest }---
工程目录
-tcdump -tcdumpTest
tcdump为dll工程核心代码实现。 tcpdumpTest为测试工程。
注意点
1、本工程基于windows不支持linux
2、本工程默认支持vs2019其他版本可以自行编译。
3、使用vs2019编译时会提示map _Node 错误只需把xtree文件中对应的 _Node 从protected修改为public并重新编译即可
4、使用前先看‘使用说明.txt’需要先注册\DIA SDK\bin\msdia120.dll。