重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

仕事でlinuxで動いているサーバーとwindowsで動いているサーバーとで通信するプログラムを開発しています。通信するデータは構造体のデータをそのままやりとししています。

ところがlinuxとVisual Studioで構造体のパックのしかたが違うためにうまくいかないケースがあって困っています。

struct aaa {
long long a;
int b;
};

この構造体についてsizeof(struct aaa) が linux(CentOS 5.3 i386) のgccだと12バイト、Visual Studio 2008(32ビット) だと16バイトになってしまいます。このためにサーバークライアントのデータの受け渡しがうまくいきません。

解決するにはどうすればよろしいでしょうか? 何らかのスイッチを指定することによりどちらかのパックの仕方をもう一方に合わせる事ができればよいのですが。

A 回答 (6件)

VisualStudioからなら・・プラグマ使ってコード上に記述追加,またはコンパイラオプションで対応できます。


#pragma pack (4)
/Zp4

サイズは12バイトになりますが実際にどうならぶかは検証が必要です。
    • good
    • 0
この回答へのお礼

ありがとうございました。
おかげさまで解決しました。

お礼日時:2009/09/05 23:39

一番簡単なのは、構造体の各メンバを文字列に変換して扱う方法です。


そうでないなら、データ長と内部表現(負値の扱いやバイトオーダーなど)を厳密に規定する必要があります。
現物合わせでたまたまうまくいったとしても、(64ビット対応など)将来のOSやコンパイラのバージョンや、別のプラットフォームが増えた場合のことを考えると、不安はつきないはずです。
    • good
    • 0

>解決するにはどうすればよろしいでしょうか?


パッキング(アライメント)を変更するオプションはありますが、
同じソースを別環境で使用する際には開発環境に依存するような作り方はよくありません。
特に、int型はシステム依存型です。単純なアライメントの変更だけでは解決できません。
Byte型の配列に対して、それぞれのメンバ変数の必要な部分を入れる等のような方法をとるべきです。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

> パッキング(アライメント)を変更するオプションはありますが、
> 同じソースを別環境で使用する際には開発環境に依存するような作り方はよくありません。

アラインメントを変更する方法が分かれば問題は解決します。そもそも、linux で動いているサーバとwindows出動いているクライアントなのでソースは全く別物です。

お礼日時:2009/09/05 22:59

適当にやるのなら、ダミーをかませて巧くいく方法をカットアンドトライで試すのもいいと思いますが、


違う処理系との通信を厳密に行うのなら、長さや符号やエンディアンの情報を決めてやり取りした方がよいかと思います。

パックの仕方もそうですが、型のビット数やsigned/unsignedを省略したときのデフォルト設定やエンディアンなど
処理系によって仕様が異なり、更にその仕様内容が保証されていないようなものであれば、その仕様には頼らないほうが無難かと思います。

例えば、全メンバが64ビットに収まるのであれば、送信元が構造体の全メンバを一旦64ビット無符号リトルエンディアンに変換し、
通信自体は単なるデータ列として送信し、それを受信側で構造体に再変換するとか。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
ただ、4バイトのダミーを入れるのは、この問題が発生した時からやっております。構造体のメンバーが変わるたびに、コメントにしたり、しなかったりするのが面倒なのでこの質問をしています。

エンディアンは両方インテル系なので問題ありません。signed、unsigned が問題になるような書き方はしておりません。

お礼日時:2009/09/05 22:56

もっとまっとうな方法は #pragma を使うことかもしれません。


両方の OS で使えればよいのですが…。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

#pragma を両方で使える必要はなく、
たとえばgccの方を#oragma またはコマンドラインスイッチで8バイトアラインメントにできればよいのですが。あるいはVsual Studioの方を#pragma またはスイッチで4バイトアラインメントにする方法が分かれば解決するのですが。

お礼日時:2009/09/05 22:51

a と b の間に 4 バイトのダミー・メンバーを入れると、


もしかしたら両 OS での構造体サイズが同じになるかもしれません。

とりあえず動けばよいのであればこの方法が使えるかもしれませんし、
本格的に対処するなら識者のかたがたから届くであろう別の方法をお使いになるのがよいかもしれません。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
ただ、4バイトのダミーを入れるのは、この問題が発生した時からやっております。構造体のメンバーが変わるたびに、コメントにしたり、しなかったりするのが面倒なのでこの質問をしています。

お礼日時:2009/09/05 22:46

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!