2012-03-28 9 views
1

動的ペイロード長を持ち、ヘッダ構造体(LEN)内の変数によって決定されるデータパケット用の構造体を作成しようとしています。構造体内の動的可変長C

これを正しく行う方法がわかりません。いくつかの例が混乱しています。ベローは私が使っているものの基礎となる構造です。おかげさまで

struct packet 
{ 
    unsigned char payload; 
    unsigned int CRC : 16; 

    struct header 
    { 
     unsigned char SRC; 
     unsigned char DST; 
     unsigned char NS : 3;  //3 bits long 
     unsigned char NR : 3; 
     unsigned char RSV : 1;  //1 bit long 
     unsigned char LST : 1; 
     unsigned char OP; 
     unsigned char LEN; 
    } HEADER; 

}; 

struct packet PACKET; 
+0

最も役立つ回答を受け入れるようにしてください。 – jncraton

+0

新しいパケットが受信されるたびにLENが変更され、ペイロードが毎回動的に変更されます。 – Friendlyghost89

+0

これを訪問すると、[回答を受け入れる] [http://meta.stackexchange.com/a/65088] – Krish

答えて

2

代わりにペイロードをポインタにして、ヘッダフィールドのLENの値に従って実行時に割り当てます。

+0

LENは、そのパケットの大きさに基づいて着信パケットによって変更されます。 – Friendlyghost89

+0

ヘッダーの長さが変わるたびにペイロードのサイズを手動で変更する必要があります。ヘッダーの長さを変更するだけで動的にサイズ変更されません*。 – Perception

3

「ストレッチアレイ」と呼ばれることもあるコンストラクトを使用できます。 (あるいは@Jerry棺が指摘するように、「可撓性アレイ部材」)可変長ペイロードを末尾にする必要がある:

struct packet 
{ 
    struct header 
    { 
     unsigned char SRC; 
     unsigned char DST; 
     unsigned char NS : 3;  //3 bits long 
     unsigned char NR : 3; 
     unsigned char RSV : 1;  //1 bit long 
     unsigned char LST : 1; 
     unsigned char OP; 
     unsigned char LEN; 
    } HEADER; 
    unsigned int CRC : 16; 
    unsigned char payload[1]; //STRETCHY. 
}; 

struct packet PACKET; 

手動でする必要があるためこのタイプの構造は、動的に割り当てられる必要がありますペイロード用に十分なスペースを確保してください。

PACKET * p = malloc(sizeof(PACKET)+payloadLength*sizeof(char)); 
p->HEADER->LEN = payloadLength; 
//fill in rest of header here. 
memcpy(p->payload, incomingData, payloadLength); 
+0

の方法を学ぶことができます。初めて「ストレッチアレイ」について聞いたことがあります。これは通常 "struct hack"と呼ばれ、(C99では) "flexible array member"と呼ばれます。フレキシブルな配列メンバーの場合は、サブスクリプトを含まないので、 'unsigned char payload [];'だけになります。 –

+0

だから、私は「時々呼ばれた」と言いました。私は店のニックネームが普遍的ではないと思った。また、私は下付き文字がC99より前に要求されたと思います。 – AShelly

+0

あなたはすべての点で正しいと思います。私は、OPにGoogleにフィードを提供することを除いて、それを持ち上げたことはないでしょう。 –

0

構造体には長さを含める必要がありますが、データは含める必要はありません。あなたがしていることに応じて、データを別々に扱います。構造体にはおそらくデータへのポインタが含まれているはずですが、構造体を逆シリアル化するときにこれを処理する必要があります。それはあなたがそれを読んだときに何も意味しません。

したがって、データフィールドのサイズを含めて構造体を書き出し、データフィールドを書き出します。 fscanf構造体を読んだら、構造体がストリームから伝えたバイトのサイズを読み込んでそれをデータとして格納し、最後にfscanfで作成した構造体に新しく読み込んだデータへのポインタを格納します。このような複数の項目を読み込んでいる場合は、その時点で次の構造体を読み込み続けてデータなどを読むことができます。

関連する問題