繁体   English   中英

如何将 const byte * 反序列化为 cpp 中的结构?

[英]How do I deserialise a const byte * to a structure in cpp?

我有这样的结构

struct foo {
 string                str1;
 uint16_t              int1
 string                str2;
 uint32_t              int2;
 string                str3;   
 };

字符串 str1、str2、str3 的长度固定为 12 字节、3 字节等。 左填充空格。

我有一个 function void func(const byte* data, const size_t len)应该将 byte * 数据转换为结构 foo。 len 是数据的长度。 我可以通过哪些方式做到这一点?

同样,数据是字节类型的 const 指针,中间不会有 null 字符来区分不同的成员。 我应该为 str1、str2、str3 使用字符数组而不是字符串吗?

最简单(但最容易出错)的方法是如果字符串具有固定长度,则只需 reinterpret_cast / std::memcpy :

// no padding
#pragma pack(push, 1)
struct foo {
 char       str1[12];
 uint16_t   int1;
 char       str2[3];
 uint32_t   int2;
 char       str3[4];   
 };
#pragma pack(pop)

void func(const byte* data, const size_t len) {
    assert(len == sizeof(foo));

    // non owning
    const foo* reinterpreted = reinterpret_cast<const foo*>(data);

    // owning
    foo reinterpreted_val = *reinterpret_cast<const foo*>(data);
   
    foo copied;
    memcpy(&copied, data, len); 
}

笔记:

稍微好一点的方法:

struct foo {
 char       str1[13];
 uint16_t   int1;
 char       str2[4];
 uint32_t   int2;
 char       str3[5];   
 };

void func(const char* data, const size_t len) {
    foo f;

    memcpy(f.str1, data, 12);
    f.str1[12] = '\0';
    data+=12;

    memcpy(&f.int1, data, sizeof(uint16_t));
    data+=sizeof(uint16_t);

    memcpy(f.str2, data, 3);
    f.str2[3] = '\0';
    data+=3;

    memcpy(&f.int2, data, sizeof(uint32_t));
    data+=sizeof(uint32_t);

    memcpy(f.str3, data, 4);
    f.str3[4] = '\0';
    data+=4;
}

笔记:

  • 您可以结合这两种方法来摆脱指针算术。 这也将解释您可能拥有的结构中的任何填充。
  1. 我认为最简单的方法是将结构内的字符串更改为 char 类型。 然后您可以根据其大小轻松复制此结构的对象。
  2. 您将不得不以某种方式处理具有不同字节顺序的机器上的字节顺序
struct foo {
    char                str1[12];
    uint16_t              int1;
    char                str2[3];
    uint32_t              int2;
    char                str3[5];
};

byte* Encode(foo* p, int Size) {
    int FullSize = Size * sizeof(foo);
    byte* Returner = new byte[FullSize];

    memcpy_s(Returner, FullSize, p, FullSize);

    return Returner;
}

foo * func(const byte* data, const size_t len) {
    int ArrSize = len/sizeof(foo);

    if (!ArrSize || (ArrSize* sizeof(foo)!= len))
        return nullptr;

    foo* Returner = new foo[ArrSize];

    memcpy_s(Returner, len, data, len);

    return Returner;
}

int main()
{
    const size_t ArrSize = 3;
    foo Test[ArrSize] = { {"Test1",1000,"TT",2000,"cccc"},{"Test2",1001,"YY",2001,"vvvv"},{"Test1",1002,"UU",2002,"bbbb"}};
    foo* Test1 = nullptr;

    byte* Data = Encode(Test, ArrSize);

    Test1 = func(Data, ArrSize * sizeof(foo));

    if (Test1 == nullptr) {
        std::cout << "Error extracting data!" << std::endl;
        delete [] Data;
        return -1;
    }

    std::cout << Test1[0].str1 << " " << Test1[1].str1 << " " << Test1[2].str3 << std::endl;

    delete [] Data;
    delete[] Test1;

    return 0;
}

output

Test1 Test2 bbbb

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM