简体   繁体   English

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

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

I have a structure like this我有这样的结构

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

strings str1, str2, str3 are of fixed length of 12 bytes, 3 bytes,etc.字符串 str1、str2、str3 的长度固定为 12 字节、3 字节等。 left padded with spaces.左填充空格。

I have a function void func(const byte* data, const size_t len) which is supposed to convert the byte * data to structure foo.我有一个 function void func(const byte* data, const size_t len)应该将 byte * 数据转换为结构 foo。 len is length of data. len 是数据的长度。 What are the ways in which I can do this?我可以通过哪些方式做到这一点?

Again the data is const pointer of byte type and will not have null characters in between to distinguish different members.同样,数据是字节类型的 const 指针,中间不会有 null 字符来区分不同的成员。 Should I use character array instead of string for str1, str2, str3?我应该为 str1、str2、str3 使用字符数组而不是字符串吗?

Easiest (but most errorprone) way is to just reinterpret_cast / std::memcpy if the strings have fixed length:最简单(但最容易出错)的方法是如果字符串具有固定长度,则只需 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); 
}

Notes:笔记:

Slightly better approach:稍微好一点的方法:

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;
}

Notes:笔记:

  • You could combine both approaches to get rid of the pointer arithmetic.您可以结合这两种方法来摆脱指针算术。 That would also account for any padding in your struct you might have.这也将解释您可能拥有的结构中的任何填充。
  1. I think the easiest way to do this is to change the string inside the structure to the type of char.我认为最简单的方法是将结构内的字符串更改为 char 类型。 Then you can easily copy the objects of this structure according to its size.然后您可以根据其大小轻松复制此结构的对象。
  2. you will have to somehow deal with the byte order on machines with different byte order您将不得不以某种方式处理具有不同字节顺序的机器上的字节顺序
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 output

Test1 Test2 bbbb

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

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