- ベストアンサー
異なる構造体のデータのコピー
- 異なる構造体のデータをコピーする方法について解説します
- 構造体のメンバのデータを別の構造体にコピーする際の方法についてご紹介します
- 異なる構造体のメンバデータのコピー方法や異なるデータ型のメンバの扱いについて解説します
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
>(1)構造体が微妙に異なるため、各メンバ変数に値をそれぞれ代入していくしか方法がないのでしょうか? struct _recvData rData; struct _sendData sData; として memcpy(&sData.data01, &rData, sizeof(rData)); という連続したメモリー領域としてコピーが可能です。 C言語では、 構造体のアドレスはその先頭のメンバーのアドレスと一致する ということが保障されています。 この手法には副作用があります。 ■ 利点 プログラムメモリの消費量が小さくなる。 ■ 欠点 送受信データの構造体の定義が反映されないため、 構造体のメンバーが変更されるとバグが発生する確率が高くなる。 構造体に個別の変数を代入方法は マクロと関数にする方法がありますが どちらが良いかは固有の問題ではなく、一般論です。 >(2)array01, array02はデータの型が異なる場合、データのコピーはどのようにしたらよいでしょうか? エンディアン (endianness)が異なる場合 バイト列を並べ替える必要があります。 例 for (u_char *s = (u_char *)&sData.array01[0], int i = sizeof(sData.array01[0])/sizeof(rData.array01[0]) - 1; i >= 0 ; i--) *s++ = (u_char)rData.array01[i]; エンディアンが等しい場合は、 他の回答にもあるように、そのままバイト列としてコピーすれば良いでしょう。 エンディアンの変換が必要である場合、 通信プロトコルのレイヤーが何処にあるかで 変換するかしないかを決定します。 アプリケーションのレイヤーでの互換性を維持する場合は、アプリケーションで それより下位の通信プロトコルの場合には その階層に一致するドライバーで変換するべきです。
その他の回答 (4)
- opera-man
- ベストアンサー率26% (111/414)
同変数名のデータをコピー。 headerは対応する変数ないので未処理。 int型は4バイト。 を前提条件として、 data1~data10までは、 memcpy()で&_recvDataを&_sendData.data01へ16バイト分コピーでOKです。 array01,array02については、どういう変換をするかという 仕様次第ではありますが、例えば char array01[4]=0x12, 0x34, 0x56, 0x78 というデータを int array01[0]=0x12345678 というように代入したいとすれば、 int array01[0]=(0x78>>24)+(0x56>>16)+(0x34>>8)+0x12 でいけると思います^^ ※もし、処理系がビックエンディアンなら、 memcpy()するサイズを48バイト分コピーでいけると思います!
- D-Matsu
- ベストアンサー率45% (1080/2394)
つ「共用体」 headerが足りない分以外は基本的に同じサイズっぽい(パディング注意)ので、recvDataの先頭にintのダミーメンバー突っ込んでしまえば一応なんとかなりそう。
- Tacosan
- ベストアンサー率23% (3656/15482)
「構造体が微妙に異なる」というか, そもそもタグが違うから別物. よって「メンバごとちまちま代入する」しかない. 特殊な条件がそろえば memcpy とかが使える場面もないわけではないが, それを考えるくらいなら「微妙に異なる」ところ以外をまとめて構造体にしてしまえ.
- asuncion
- ベストアンサー率33% (2127/6289)
>(1)構造体が微妙に異なるため、各メンバ変数に値をそれぞれ代入していくしか方法がないのでしょうか? おそらく、そうせざるを得ないと思います。 >(2)array01, array02はデータの型が異なる場合、データのコピーはどのようにしたらよいでしょうか? 入力データがどうなっているときに、出力データをどうしたいかによると思います。 エンディアンが関係するかもしれません。 ところで、data03~data10は、配列にするわけにはいかないのでしょうか。