2012-01-19 11 views
0

私は3バイト(24ビット)をバイナリプロトコルで実装する必要があります。元の値はint(32ビット)に格納されます。はC++で4バイトから3バイトに変換します

Technique1: - - :

long x = 24; 
long y = htonl(x); 
long z = y>>8; 
memcpy(dest, z, 3); 

それを行うための正しい方法である上記の場合は私に知らせてください、次のようにこれを達成する1つの方法は、でしょうか?

私は理解しない他の方法は、

Technique2以下のように実装されました: - 私は理解しない何

typedef struct { 
char data1; 
char data2[3]; 
} some_data; 

typedef union { 
long original_data; 
some_data data; 
} combined_data; 

long x = 24; 

combined_data somedata; 
somedata.original_data = htonl(x); 

memcpy(dest, &combined_data.data.data2, 3); 

で、3つのバイトがようcombined_data.data.data2に終わるでしたか最初のバイトはcombined_data.data.data1に入り、次の2バイトは combined_data.data.data2に入りますか?

これは、2.6.x Linuxおよびgccを実行するx86_64プラットフォームです。

部分的に対応: - x86_64プラットフォームでは、メモリは右から左にアドレス指定されます。そう値24とlong型の変数、htonl有するメモリ表現

|--Byte4--|--Byte3--|--Byte2--|--Byte1--| 
    0   0   0  0x18 

を以下ているであろうが()long型の上で行われ、メモリは

構造体SOME_DATAで
|--Byte4--|--Byte3--|--Byte2--|--Byte1--| 
    0x18  0   0   0 

なります
data1 = Byte1 
data2[0] = Byte2 
data2[1] = Byte3 
data4[2] = Byte4 

私の質問はまだ成り立っていますが、テクニック1に示すように、8だけ右シフトしてみませんか?

+2

は、おそらくエンディアンとは何かを持っています。 –

答えて

2

バイトは、あなたが何も変更されていない0で移動

int x = 24; 
int y = x<<8; 

:-) 8ビットを取ります。 1 - * 2、2 - * 4、8 - * 256。

私たちがBIG ENDIANマシン上にいる場合、4バイトは2143としてメモリに格納されます。このような偽装は、2^15を超える数では機能しません。逆に、BIG ENDIANマシンでは、「3バイトで整数を入れる」という意味を定義する必要があります。

Hmm。私が思うに、2番目に提案されたalgorythmはOKですが、バイトの順序を変更してください:

あなたは2143として持っています。あなたは321が必要だと思います。しかし、それをよく点検してください。

編集:私は、ウィキで確認 - のx86はリトルエンディアンである、彼らは言う、algorythmsはOKですので

+0

私の理解では、ビットは0から7の番号が付けられ、1から8の番号は付けられていません。 – Jimm

+2

'8'はシフトしているビット位置の数を表します。シフトすると0は表示されません。 –

+1

@ Jimm:ビットにはどのようなラベルがあるかは関係ありません。 'x << 8'は' x 'を8ビットシフトします。 –

関連する問題