0

boost::asioの送信者/受信者のために構造体をシリアル化するためにユニオンを使用している人はいないのだろうか。私は何かを検索しましたが、私が見つけたのは(まだ)このような例これだけでした。

だから私はそれをこのようにやった:

struct ST {
  short a;
  long b;
  float c;
  char c[256];
}
... 

void sender::send(const ST &_packet) {
  union {
    const ST &s;
    char (&c)[sizeof(ST)];
  }usc = {_packet};

  socket.send_to(boost::asio::buffer(usc.c, sizeof(ST)), endpoint);
}
...

ST var = {1234, -1234, 1.4567, "some text"};
sercer.send(var);

だから私の質問は、基本的なデータ型のシリアル化を行うためのこの悪い習慣ですか?

var-sizeの文字列を直接送信できないことはわかっているので、boost::serializationを使用できます。

4

1 に答える 1

1

それは確かに悪い習慣です。送信するのは(想定される)システム上のユニオンにあるものの正確なバイナリ表現を含む一連のバイトです。問題は次のとおりです。

  1. uscユニオンにSTを入力しますが、char []としてアクセスすると、未定義の動作が発生します(ただし、おそらくすべての一般的なシステムで機能します)。
  2. おそらく、受信側でも同じことを逆の順序で実行する必要があります。再びUBですが、おそらく動作します。
  3. ここで問題が発生します。同じ構造体定義に対して、受信側システムで同じである必要はないシステム固有の形式でデータを送信します。これも
    • 整数型のバイトオーダー(リトルエンディアン/ビッグエンディアン)
    • 整数型だけでなく、型のサイズ(たとえば、sizeof(long)が32ビットシステムから64ビットシステムまで、または64ビットシステム上の異なるコンパイラ間で異なる場合があります)
    • バイトのパディング
    • sizeof(ST)自体は大幅に異なる場合があります

簡単に言うと、これは行わないでください。とにかくboost::serializationを使用している場合は、その中の文字列だけでなく、ST構造体全体に使用してください。データ構造がもう少し複雑になった場合(たとえば、ポインターが含まれている、重要なコンストラクターがあるなど)、とにかくそれを行う必要があります。

于 2013-02-14T15:26:15.543 に答える