簡體   English   中英

從byte []到struct的類型轉換

[英]Typecasting from byte[] to struct

我目前正在研究一個小型C ++項目,在這里我使用別人構建的客戶端-服務器模型。 數據是通過網絡發送的,我認為順序錯誤。 但是,這不是我可以更改的。

示例數據流(簡化):

0x20 0x00 (C++: short with value 32)
0x10 0x35 (C++: short with value 13584)
0x61 0x62 0x63 0x00 (char*: abc)
0x01 (bool: true)
0x00 (bool: false)

我可以將此特定流表示為:

struct test {
    short sh1;
    short sh2;
    char abc[4];
    bool bool1;
    bool bool2;
}

我可以使用test *t = (test*)stream;進行類型轉換test *t = (test*)stream; 但是,char *具有可變長度。 但是,它始終為null終止。

我了解沒有辦法將流實際轉換為結構,但是我想知道是否有比struct test() { test(char* data) { ... }} (通過構造函數轉換struct test() { test(char* data) { ... }}更好的方法)

這稱為編組序列化

您必須做的是一次讀取一個字節流(或將其全部放入緩沖區並從中讀取),並且一旦有足夠的數據供結構中的成員使用,就填充它。

當涉及到字符串時,您只需讀取直到達到終止零,然后分配內存並將該字符串復制到該緩沖區,然后將其分配給該結構中的指針即可。

如果您已經將消息存儲在緩沖區中,則以這種方式讀取字符串是最簡單且最有效的,因為這樣就不需要為該字符串設置臨時緩沖區。

但是請記住,使用此方案時,必須在完成結構后手動釋放包含字符串的內存。

只需添加一個成員函數,該成員函數接受字符緩沖區(函數輸入參數char * )並通過對其進行分析來填充test結構。
這也使它更清晰易讀。

如果提供隱式轉換構造函數,則會創建一個威脅,它將在您最不期望的時候進行轉換。

從字節序列讀取可變長度數據時,不應將所有內容都放入單個結構或變量中。 指針還用於存儲此可變長度。

以下建議未經測試:

// data is stored in memory,
// in a different way,
// NOT as sequence of bytes,
// as provided
struct data {
    short sh1;
    short sh2;
    int abclength;
    // a pointer, maybe variable in memory !!!
    char* abc;
    bool bool1;
    bool bool2;
};

// reads a single byte
bool readByte(byte* MyByteBuffer)
{
    // your reading code goes here,
    // character by character, from stream,
    // file, pipe, whatever.
    // The result should be true if not error,
    // false if cannot rea anymore
}

// used for reading several variables,
// with different sizes in bytes
int readBuffer(byte* Buffer, int BufferSize)
{
    int RealCount = 0;

    byte* p = Buffer;

    while (readByte(p) && RealCount <= BufferSize)
    {
        RealCount++
        p++;
    }

    return RealCount;
}

void read()
{
    // real data here:
    data Mydata;

    byte MyByte = 0;

    // long enough, used to read temporally, the variable string
    char temp[64000];
    // fill buffer for string with null values
    memset(temp, '\0', 64000);

    int RealCount = 0;

    // try read "sh1" field
    RealCount = (readBuffer(&(MyData.sh1), sizeof(short)));
    if (RealCount == sizeof(short))
    {
        // try read "sh2" field
        RealCount = readBuffer(&(MyData.sh2), sizeof(short));       
        if (RealCount == sizeof(short))
        {
            RealCount = readBuffer(temp, 64000);
            if (RealCount > 0)
            {
                // store real bytes count
                MyData.abclength = RealCount;
                // allocate dynamic memory block for variable length data
                MyData.abc = malloc(RealCount);
                // copy data from temporal buffer into data structure plus pointer
                // arrays in "plain c" or "c++" doesn't require the "&" operator for address:
                memcpy(MyData.abc, temp, RealCount);

                // comented should be read as:
                //memcpy(&MyData.abc, &temp, RealCount);

                // continue with rest of data
                RealCount = readBuffer(&(MyData.bool1), sizeof(bool));
                if (RealCount > 0)
                {
                    // continue with rest of data
                    RealCount = readBuffer(&(MyData.bool2), sizeof(bool));
                }
            }
        }
    }
} // void read()

干杯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM