qicosmos/iguana

error: 序列化char时候出错

Opened this issue · 11 comments

简述:
我写了一个结构体测试,其中有一个char类型的成员。
通过结构体序列化转换得到了一个错误的json。少了一个 ‘,’。
{"U8":","U16":22,"U32":50,"U64":100,"DOUBLE":2E0,"FLOAT":-1E0,"S8":"","S16":-16,"S32":-32,"S64":-64,"STR":"ABC"}

代码如下

#include <iguana/json_reader.hpp>
#include <iguana/json_writer.hpp>

using u8 = char;
using u16 = uint16_t;
using u32 = uint32_t;
using u64 = uint64_t;
using s8 = char;
using s16 = int16_t;
using s32 = int32_t;
using s64 = int64_t;

struct Test{
    u8 U8 = 0xa1; //
    u16 U16 = 0x16;//
    u32	U32 = 0x32;//
    u64 U64 = 0x64;//
    double DOUBLE = 2.0;
    float FLOAT = -1.0;
    s8  S8= -1; //
    s16 S16 = -16;//
    s32	S32 = -32;//
    s64 S64 = -64;//
    char STR[50] ="ABC";
};
REFLECTION(Test, U8, U16,U32,U64,DOUBLE, FLOAT, S8,S16,S32,S64,STR);

int main(int argc, char *argv[]) {

    Test p;

    iguana::string_stream ss;
    iguana::to_json(p, ss);

    qDebug() << QString::fromStdString(ss) ;
    std::cout << ss << std::endl;
}
1690723250622

另一个例子,似乎关于char,这个类型就存在问题。
1690723464166

bbbgan commented

其中char是 0xa1, ascii码数字为161,并不是有效的ASCII码数字。然后 0x11,是17,是控制字符,这些字符不能正常显示也是合理的吧

bbbgan commented

也许你需要的是显示数字的 int8_t这种类型?但是似乎目前还没有支持,因为担心其与char的兼容性。

也许你需要的是显示数字的 int8_t这种类型?但是似乎目前还没有支持,因为担心其与char的兼容性。

是的 我实际需要的是 uint8_t这种类型。 这种类型在和嵌入式设备通信中经常用到。希望能够支持上。

也许你需要的是显示数字的 int8_t这种类型?但是似乎目前还没有支持,因为担心其与char的兼容性。

是的 我实际需要的是 uint8_t这种类型。 这种类型在和嵌入式设备通信中经常用到。希望能够支持上。
关于char 这种数据结构,可以考虑用 类似 hex字符串的形式 。

其中char是 0xa1, ascii码数字为161,并不是有效的ASCII码数字。然后 0x11,是17,是控制字符,这些字符不能正常显示也是合理的吧

这里应该不只是不能显示。还会导致 输出的字符串不满足json 的规则。无法解析。 或者不支持的情况下,直接跳过或者空。

@RichardsATcn 有其它什么json 库支持这种输出吗?

@RichardsATcn 有其它什么json 库支持这种输出吗?
目前我也没有找到其他c++的json库支持这种输出。c++的反射获取成本实在太高了。
由于 uint8_t 刚好是8位处理器的一个寄存器长度。 uint8_t这种类型,不仅仅会单个出现,还有会用到 uint8_t data[10]。因为处理器资源的情况。很少使用类似 array动态数组。这种定长的结构体可以直接 通过1字节对齐的方式,直接拷贝内存块获得字节序列,用于传输。
我下面这几种种输出方式都是自己在项目中使用Qt QGadget的反射 配合人工编码获得的。 之所以除了base64 的方式 还用hex的方式,因为嵌入式工程师调试协议时候对 hex会比base64敏感的多。

 uint8_t  u8  =  0x22; // =>  { "U8": "0x22"}
 uint8_t  u8Buf[10] ;// =>  { "U8BUF": "064|base64 str"}
 uint8_t  u8Buf[10] ; // =>  { "U8BUF": "016|AABBCC"} 
bbbgan commented

我尝试支持一下uint8吧那,如果支持了uint8你的问题可以得到解决了吗?

bbbgan commented

我刚刚测试了一下,gcc和clang可以区分开int8_t 、uint8_t与char的,windows应该也可以!但是我不知道您的编译器是否可以,

bbbgan commented

支持了uint8和int8,可以拉取最新的代码试试看

我刚刚测试了一下,gcc和clang可以区分开int8_t 、uint8_t与char的,windows应该也可以!但是我不知道您的编译器是否可以,

好的,您真是迅速呀。 我的编译器是 vs2019 和 mingw 8.1.0