- ベストアンサー
構造体のパックの仕様の違いについて
- 構造体のパックの仕様の違いにより通信プログラムが正常に動作しない問題が発生しています。
- linuxとWindowsで構造体のパックの方法が異なり、データの受け渡しに問題が生じる可能性があります。
- どちらかのパックの仕方を他方に合わせることで問題を解決することができます。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
VisualStudioからなら・・プラグマ使ってコード上に記述追加,またはコンパイラオプションで対応できます。 #pragma pack (4) /Zp4 サイズは12バイトになりますが実際にどうならぶかは検証が必要です。
その他の回答 (5)
- jacta
- ベストアンサー率26% (845/3158)
一番簡単なのは、構造体の各メンバを文字列に変換して扱う方法です。 そうでないなら、データ長と内部表現(負値の扱いやバイトオーダーなど)を厳密に規定する必要があります。 現物合わせでたまたまうまくいったとしても、(64ビット対応など)将来のOSやコンパイラのバージョンや、別のプラットフォームが増えた場合のことを考えると、不安はつきないはずです。
- SilverThaw
- ベストアンサー率32% (260/806)
>解決するにはどうすればよろしいでしょうか? パッキング(アライメント)を変更するオプションはありますが、 同じソースを別環境で使用する際には開発環境に依存するような作り方はよくありません。 特に、int型はシステム依存型です。単純なアライメントの変更だけでは解決できません。 Byte型の配列に対して、それぞれのメンバ変数の必要な部分を入れる等のような方法をとるべきです。
お礼
ご回答ありがとうございます。 > パッキング(アライメント)を変更するオプションはありますが、 > 同じソースを別環境で使用する際には開発環境に依存するような作り方はよくありません。 アラインメントを変更する方法が分かれば問題は解決します。そもそも、linux で動いているサーバとwindows出動いているクライアントなのでソースは全く別物です。
- midly
- ベストアンサー率40% (24/59)
適当にやるのなら、ダミーをかませて巧くいく方法をカットアンドトライで試すのもいいと思いますが、 違う処理系との通信を厳密に行うのなら、長さや符号やエンディアンの情報を決めてやり取りした方がよいかと思います。 パックの仕方もそうですが、型のビット数やsigned/unsignedを省略したときのデフォルト設定やエンディアンなど 処理系によって仕様が異なり、更にその仕様内容が保証されていないようなものであれば、その仕様には頼らないほうが無難かと思います。 例えば、全メンバが64ビットに収まるのであれば、送信元が構造体の全メンバを一旦64ビット無符号リトルエンディアンに変換し、 通信自体は単なるデータ列として送信し、それを受信側で構造体に再変換するとか。
お礼
ご回答ありがとうございます。 ただ、4バイトのダミーを入れるのは、この問題が発生した時からやっております。構造体のメンバーが変わるたびに、コメントにしたり、しなかったりするのが面倒なのでこの質問をしています。 エンディアンは両方インテル系なので問題ありません。signed、unsigned が問題になるような書き方はしておりません。
- asuncion
- ベストアンサー率33% (2127/6289)
もっとまっとうな方法は #pragma を使うことかもしれません。 両方の OS で使えればよいのですが…。
お礼
ご回答ありがとうございます。 #pragma を両方で使える必要はなく、 たとえばgccの方を#oragma またはコマンドラインスイッチで8バイトアラインメントにできればよいのですが。あるいはVsual Studioの方を#pragma またはスイッチで4バイトアラインメントにする方法が分かれば解決するのですが。
- asuncion
- ベストアンサー率33% (2127/6289)
a と b の間に 4 バイトのダミー・メンバーを入れると、 もしかしたら両 OS での構造体サイズが同じになるかもしれません。 とりあえず動けばよいのであればこの方法が使えるかもしれませんし、 本格的に対処するなら識者のかたがたから届くであろう別の方法をお使いになるのがよいかもしれません。
お礼
ご回答ありがとうございます。 ただ、4バイトのダミーを入れるのは、この問題が発生した時からやっております。構造体のメンバーが変わるたびに、コメントにしたり、しなかったりするのが面倒なのでこの質問をしています。
お礼
ありがとうございました。 おかげさまで解決しました。