C++ 将DLL返回结构体编码转语义字符串并输出JSON方案咨询
实现方案
方案1:静态映射表实现(最适配你的场景)
你的码值总量少(20个错误码、10个警告码、15个状态码),用静态映射表性能最高、维护也简单,完全适配你的需求,实现步骤如下:
首先定义各编码的映射表和通用转换函数:
#include <nlohmann/json.hpp> #include <unordered_map> #include <string> #include <cstring> using json = nlohmann::json; // 状态码映射 const std::unordered_map<BYTE, std::string> status_map = { {0x00, "no_error"}, {0x01, "error"}, {0x02, "ready"}, {0x05, "power_off"}, // 剩余状态码按需补全 }; // 错误码映射 const std::unordered_map<BYTE, std::string> error_map = { {0x00, "no_error"}, {0x01, "error_system_fail"}, {0xFF, "unknown_error"}, // 剩余错误码按需补全 }; // 警告码映射:将两个DWORD拼接为64位值作为key const std::unordered_map<uint64_t, std::string> warning_map = { {0x0000000000000000, "no_warning"}, {0x0000000200000001, "warning_alert"}, // 剩余警告码按需补全 }; // 通用码值转语义函数 template<typename T> std::string get_code_desc(const T& code, const std::unordered_map<T, std::string>& map) { auto it = map.find(code); return it != map.end() ? it->second : "unknown"; } // 警告码特殊处理函数 std::string get_warning_desc(DWORD code[2]) { uint64_t key = (static_cast<uint64_t>(code[0]) << 32) | code[1]; auto it = warning_map.find(key); return it != warning_map.end() ? it->second : "unknown"; }
修改你的JSON生成逻辑,匹配目标格式:
GetInfoStatus(&myStatusStruct); // 每个字段按[码值, 语义]数组格式存储 jInfo["error_code"] = json::array({myStatusStruct.ErrorCode, get_code_desc(myStatusStruct.ErrorCode, error_map)}); jInfo["status_code"] = json::array({myStatusStruct.StatusCode, get_code_desc(myStatusStruct.StatusCode, status_map)}); uint64_t warning_key = (static_cast<uint64_t>(myStatusStruct.WarningCode[0]) << 32) | myStatusStruct.WarningCode[1]; jInfo["warning_code"] = json::array({warning_key, get_warning_desc(myStatusStruct.WarningCode)}); jInfo["is_available_warning_code"] = json::array({myStatusStruct.AvailableWarningCode2, myStatusStruct.AvailableWarningCode2 ? "available" : "unavailable"}); std::string info = jInfo.dump(); // 注意:不能直接返回局部字符串的c_str(),局部变量销毁后指针会悬空,改为拷贝到堆内存返回,外部使用完后释放即可 char* res = new char[info.size() + 1]; strcpy(res, info.c_str()); return res;
注意:JSON标准不支持十六进制字面量写法,你示例中的
0x01属于非标准格式,大部分JavaScript/Node.js的JSON解析器无法正常解析。如果需要保留十六进制标识,建议把码值转为十六进制字符串存储,如["0x01", "warning_alert"],仅需新增一个数值转十六进制字符串的工具函数即可实现。
如果追求更高性能,由于状态码、错误码都是BYTE类型,取值范围仅0-255,可以用数组替代哈希表做映射,访问速度更快:
const std::string status_map[256] = { [0x00] = "no_error", [0x01] = "error", [0x02] = "ready", // 未定义的码值默认返回空,可在转换函数统一处理为"unknown" };
方案2:X Macro宏实现(适合码值频繁变动的场景)
如果后续码值需要频繁增删,不想同时维护码值定义和映射表,可以用X Macro语法统一维护,避免两边修改漏项:
// 所有状态码统一在这里维护,增删仅需修改此处 #define STATUS_CODE_LIST \ X(0x00, "no_error") \ X(0x01, "error") \ X(0x02, "ready") \ X(0x05, "power_off") // 自动生成映射表 const std::unordered_map<BYTE, std::string> status_map = { #define X(code, desc) {code, desc}, STATUS_CODE_LIST #undef X };
内容的提问来源于stack exchange,提问作者rockstiff
相关产品推荐
相关产品推荐

