パケットにデータをパックしようとしています。このパケットは64ビットでなければなりません。私はこれを持っています:ビットフィールドとアラインメント
typedef union {
uint64_t raw;
struct {
unsigned int magic : 8;
unsigned int parity : 1;
unsigned int stype : 8;
unsigned int sid : 8;
unsigned int mlength : 31;
unsigned int message : 8;
} spacket;
} packet_t;
しかし、アライメントは保証されていないようです。
#include <strings.h>
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
const char *number_to_binary(uint64_t x)
{
static char b[65];
b[64] = '\0';
uint64_t z;
int w = 0;
for (z = 1; w < 64; z <<= 1, ++w)
{
b[w] = ((x & z) == z) ? '1' : '0';
}
return b;
}
int main(void)
{
packet_t ipacket;
bzero(&ipacket, sizeof(packet_t));
ipacket.spacket.magic = 255;
printf("%s\n", number_to_binary(ipacket.raw));
ipacket.spacket.parity = 1;
printf("%s\n", number_to_binary(ipacket.raw));
ipacket.spacket.stype = 255;
printf("%s\n", number_to_binary(ipacket.raw));
ipacket.spacket.sid = 255;
printf("%s\n", number_to_binary(ipacket.raw));
ipacket.spacket.mlength = 2147483647;
printf("%s\n", number_to_binary(ipacket.raw));
ipacket.spacket.message = 255;
printf("%s\n", number_to_binary(ipacket.raw));
}
私は(ビッグエンディアン)を取得::私はこれを実行したときので、それは.sid
フィールドの横に右でなければなりませんが、
1111111100000000000000000000000000000000000000000000000000000000
1111111110000000000000000000000000000000000000000000000000000000
1111111111111111100000000000000000000000000000000000000000000000
1111111111111111111111111000000000000000000000000000000000000000
1111111111111111111111111000000011111111111111111111111111111110
1111111111111111111111111000000011111111111111111111111111111110
マイ.mlength
フィールドが右側の部分のどこかに失われます。
This page「ビットフィールドを保持するアロケーションユニットのアライメント」を確認します。しかし、これが当てはまるとすれば、人々はどのようにして最初の目的であるビットフィールドにデータをパックしていますか?
フィールドが追い越される前にフィールドが取り出せる最大サイズは、24ビットであると思われます。.message
フィールドは除外されます。
一般に、ビットフィールド内のデータの配置方法に依存することはできません。単語に複数のデータをパックする必要がある場合は、手動でマーシャリングを行う必要があります。 – fuz
あなたの構造体は32 * 6ビットです...代わりに文字を使用する必要があります。 – xvan
Cのデータ構造に特定のメモリレイアウトを使用しないでください。あまりにも多くの実装定義とコンパイラ固有のパラメータがあります。 @FUZxxlが書いたように、適切なマーシャリングを使用してください。良いコンパイラでは、これは必ずしも遅くなるわけではありません。 – Olaf