簡體   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