5

文字/バイトの配列であるネットワーク経由の送信を取得します。ヘッダーといくつかのデータが含まれています。ヘッダーを構造体にマップしたいと思います。次に例を示します。

#pragma pack(1)

struct Header
{
    unsigned short bodyLength;
    int msgID;
    unsigned short someOtherValue;
    unsigned short protocolVersion;
};

int main()
{
    boost::array<char, 128> msgBuffer;
    Header header;

    for(int x = 0; x < sizeof(Header); x++)
        msgBuffer[x] = 0x01; // assign some values

    memcpy(&header, msgBuffer.data(), sizeof(Header));

    system("PAUSE");    

    return 0;
}

構造体に可変長フィールドが含まれていないと仮定すると、これは常に機能しますか? これを行うプラットフォームに依存しない/慣用的な方法はありますか?

ノート:

シリアル化/逆シリアル化を可能にするライブラリをインターネット上でかなり見てきましたが、以前に同じライブラリでシリアル化されている場合にのみ、何かを逆シリアル化できるという印象を受けました。ええと、私は送信の形式を制御できません。私は間違いなく、すべての値が互いに続くバイト/文字配列を取得するつもりです。

4

6 に答える 6

5

一部のプロセッサでは、特定の型が適切に配置されている必要があります。指定されたパッキングを受け入れず、ハードウェア トラップを生成します。

また、一般的な x86 パック構造でも、コードの実行が遅くなる可能性があります。

また、エンディアンが異なるプラットフォームを使用する場合は注意が必要です。

ところで、多くのプログラミング言語にバインドされたシンプルでプラットフォームに依存しない通信メカニズムが必要な場合は、YAMIをご覧ください。

于 2009-02-06T11:30:35.020 に答える
0

誰と通信しているかを知っているので、エンディアンについて心配する必要はありません。とにかく、コンパイラ固有のコマンドには近づかないのが好きです。

では、これはどうですか:

const int kHeaderSizeInBytes = 6;

struct Header
{
    unsigned short bodyLength;
    unsigned short msgID;
    unsigned short protocolVersion; 

    unsigned short convertUnsignedShort(char inputArray[sizeof(unsigned short)])
        {return (((unsigned char) (inputArray[0])) << 8) + (unsigned char)(inputArray[1]);}

    void operator<<(char inputArray[kHeaderSizeInBytes])
    {
        bodyLength = convertUnsignedShort(inputArray);
        msgID = convertUnsignedShort(inputArray + sizeof(bodyLength));
        protocolVersion = convertUnsignedShort(inputArray + sizeof(bodyLength) + sizeof(msgID));
    }
};

int main()
{
    boost::array<char, 128> msgBuffer;
    Header header;

    for(int x = 0; x < kHeaderSizeInBytes; x++)
        msgBuffer[x] = x;

    header << msgBuffer.data();

    system("PAUSE");    

    return 0;
}

プラグマを取り除きますが、私が望むほど汎用的ではありません。ヘッダーにフィールドを追加するたびに、 << 関数を変更する必要があります。何らかの方法で構造体フィールドを反復処理し、フィールドの型を取得して、対応する関数を呼び出すことはできますか?

于 2009-02-06T12:16:30.853 に答える