質問

私に変換する必要があるのは、ビットフィールド構造から少しトルエンディアンビッグ-endiaます。何が最良の方法などがありますの課題のバイト境界までスワップの構造です。

Ex構造:

struct {
    unsigned int    b1:1;
    unsigned int    b2:8;
    unsigned int    b3:7;
    unsigned int    b4:8;
    unsigned int    b5:7;
    unsigned int    b6:1;
}; 
役に立ちましたか?

解決 8

こういったソリューション(一部からepatelソリューション。この場合いから変換x86をSolaris SPARC.

る必要がありま最初のスワップの受信sturctureとしての要素を逆順です。基本的には後方の構造がallignedまた、こういうのendianess変更の両方のバイト順序は、ビットの順序づけを行います。こちらは擬似コードです。

struct orig
{    
    unsigned int    b1:1;
    unsigned int    b2:8;
    unsigned int    b3:7;
    unsigned int    b4:8;
    unsigned int    b5:7;
    unsigned int    b6:1;
};

struct temp
{    
    unsigned int    b6:1;
    unsigned int    b5:7;
    unsigned int    b4:8;
    unsigned int    b3:7;
    unsigned int    b2:8;
    unsigned int    b1:1;
}temp;


func (struct orig *toconvert)
{
    struct temp temp_val;
    //Swap the bytes
    swap32byte((u32*)toconvert);
    //Now read the structure in reverse order - bytes have been swapped
    (u32*)&temp_val = (u32 *)toconvert;
    //Write it back to orignal structure
    toconvert->b6=temp_val.b6;
    toconvert->b5=temp_val.b5;
    toconvert->b4=temp_val.b4;
    toconvert->b3=temp_val.b3;
    toconvert->b2=temp_val.b2;
    toconvert->b1=temp_val.b1;

}

その後実験をしいていることを明らかにしたアプローチが有効な場合、要素を完全に埋構造、すなわちありません未使用ビット.

他のヒント

は、32ビットの整数を使用し、アンド及びビットシフト演算子を使用してそれから情報を抽出することができました。それに代わって、あなたは、単に(ホストとネットワーク、ロング)htonl使用することができます。ネットワークバイトオーダーはビッグエンディアンです。

このビットフィールドのようにエレガントではありませんが、少なくともあなたが持っているものを知っているだろうし、あなたの構造をパディングコンパイラを心配する必要はありません。

プロセッサのエンディアンは、ビットフィールドの順序とは無関係です。これは、ビットフィールドのために発注反対側の同じコンピュータの使用上の2つのコンパイラを持つことは可能です。だから、これを与えられます:

union {
    unsigned char x;
    struct {
        unsigned char b1 : 1;
        unsigned char b2 : 7;
    };
} abc;
abc.x = 0;
abc.b1 = 1;
printf( "%02x\n", abc.x );

は、詳細なドキュメントを持って起こる場合を除き、それは01または80をプリントアウトするかどうかを知るための唯一の方法は、それを試してみることです。

私たちは、このようにやったのLinux / x86のにMIPSからプロジェクトポーティングコードでます。

struct {

#ifdef __ONE_ENDIANESS__
    unsigned int    b1:1;
    unsigned int    b2:8;
    unsigned int    b3:7;
    unsigned int    b4:8;
    unsigned int    b5:7;
    unsigned int    b6:1;
#define _STRUCT_FILLED
#endif /* __ONE_ENDIANESS__ */

#ifdef __OTHER_ENDIANESS__
    unsigned int    b6:1;
    unsigned int    b5:7;
    unsigned int    b4:8;
    unsigned int    b3:7;
    unsigned int    b2:8;
    unsigned int    b1:1;
#define _STRUCT_FILLED
#endif /* __OTHER_ENDIANESS__ */

};

#ifndef _STRUCT_FILLED
#  error Endianess uncertain for struct
#else
#  undef _STRUCT_FILLED
#endif /* _STRUCT_FILLED */

マクロ__ONE_ENDIANESS____OTHER_ENDIANESS__は、我々はあなたがあなたのために適切であるを検討する必要がある場合がありますので、使用しているコンパイラに適した...

あなたが(最初の3つのフィールドと最後の三つのフィールドは16ビットである)が2つの16ビット部分を有している。

これはのみ65536エントリです。だから、フィールドのビット反転バージョンを保持しているルックアップテーブルを持っています。これを容易にするために2つの16ビットフィールドを持つ別の構造体と組合に構造体をラップ?

(未テストが、私はCコンパイラの近くにいないよ)のような何かます:

union u {
    struct {
        unsigned int    b1:1;
        unsigned int    b2:8;
        unsigned int    b3:7;
        unsigned int    b4:8;
        unsigned int    b5:7;
        unsigned int    b6:1;
     } bits;
     struct {
        uint16 first;
        uint16 second;
     } words
} ;

unit16 lookup[65536];

/* swap architectures */

void swapbits ( union u *p)
{
   p->words.first = lookup[p->words.first];
   p->words.second = lookup[p->words.second];
}

ルックアップテーブルの集団は読者の練習として残し

しかし、慎重にあなたのコンパイラのドキュメントをお読みください。 C標準では(私はほとんどのコンパイラはそれを行うことを期待したいが)構造体は、言葉に収まるようにすることを必要とする場合、私はわからない。

あなたは、チャネル(ファイル、またはネットワーク)とあなたの構造体との間にこれをやってみたいです。私の好ましい実施は、既知の表現でファイルバッファを構築書き込みコードによって構造からファイルI / Oを分離することであり、マッチングがその変換を反転コードを読み取る。

ビットフィールドは、unsigned int型とsizeof(unsigned int)になるように定義されているので、

あなたの具体的な例としては、推測することが特に困難である特に非ポータブルでます。

その後、構造体へのポインタを取得し、個々のバイトをreording sizeof(int)==4 SWAGはおそらくあなたが望む答えを得るように、

と仮定します。

、異なるプラットフォームごとに異なる構造体を定義するのトリックは<全角> の仕事かもしれないが、一例では、あなたはバイト境界でクリーンな休憩がない引用ので、それを製造することが可能になりそうではありません二枚に1つ以上のフィールドを分割せずに、他の内の1つのプラットフォームに相当

バイトをスワップするのに十分でなければなりません。バイト内のビット位置は、ビッグエンディアンとリトルエンディアンで同じである。
例えば:

char* dest = (char*)&yourstruct;
unsigned int orig = yourstruct;
char* origbytes = (char*)&orig;
dest[0] = origbytes[3];
dest[1] = origbytes[2];
dest[2] = origbytes[1];
dest[3] = origbytes[0];

物理的なレイアウトが重要であるとき、それは実装定義する大きな単語が移入され注文であるため、あなたはビットフィールドを使用しないでください。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top