
仕事で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バイトになってしまいます。このためにサーバークライアントのデータの受け渡しがうまくいきません。
解決するにはどうすればよろしいでしょうか? 何らかのスイッチを指定することによりどちらかのパックの仕方をもう一方に合わせる事ができればよいのですが。
No.5
- 回答日時:
一番簡単なのは、構造体の各メンバを文字列に変換して扱う方法です。
そうでないなら、データ長と内部表現(負値の扱いやバイトオーダーなど)を厳密に規定する必要があります。
現物合わせでたまたまうまくいったとしても、(64ビット対応など)将来のOSやコンパイラのバージョンや、別のプラットフォームが増えた場合のことを考えると、不安はつきないはずです。
No.4
- 回答日時:
>解決するにはどうすればよろしいでしょうか?
パッキング(アライメント)を変更するオプションはありますが、
同じソースを別環境で使用する際には開発環境に依存するような作り方はよくありません。
特に、int型はシステム依存型です。単純なアライメントの変更だけでは解決できません。
Byte型の配列に対して、それぞれのメンバ変数の必要な部分を入れる等のような方法をとるべきです。
ご回答ありがとうございます。
> パッキング(アライメント)を変更するオプションはありますが、
> 同じソースを別環境で使用する際には開発環境に依存するような作り方はよくありません。
アラインメントを変更する方法が分かれば問題は解決します。そもそも、linux で動いているサーバとwindows出動いているクライアントなのでソースは全く別物です。
No.3
- 回答日時:
適当にやるのなら、ダミーをかませて巧くいく方法をカットアンドトライで試すのもいいと思いますが、
違う処理系との通信を厳密に行うのなら、長さや符号やエンディアンの情報を決めてやり取りした方がよいかと思います。
パックの仕方もそうですが、型のビット数やsigned/unsignedを省略したときのデフォルト設定やエンディアンなど
処理系によって仕様が異なり、更にその仕様内容が保証されていないようなものであれば、その仕様には頼らないほうが無難かと思います。
例えば、全メンバが64ビットに収まるのであれば、送信元が構造体の全メンバを一旦64ビット無符号リトルエンディアンに変換し、
通信自体は単なるデータ列として送信し、それを受信側で構造体に再変換するとか。
ご回答ありがとうございます。
ただ、4バイトのダミーを入れるのは、この問題が発生した時からやっております。構造体のメンバーが変わるたびに、コメントにしたり、しなかったりするのが面倒なのでこの質問をしています。
エンディアンは両方インテル系なので問題ありません。signed、unsigned が問題になるような書き方はしておりません。
No.1
- 回答日時:
a と b の間に 4 バイトのダミー・メンバーを入れると、
もしかしたら両 OS での構造体サイズが同じになるかもしれません。
とりあえず動けばよいのであればこの方法が使えるかもしれませんし、
本格的に対処するなら識者のかたがたから届くであろう別の方法をお使いになるのがよいかもしれません。
ご回答ありがとうございます。
ただ、4バイトのダミーを入れるのは、この問題が発生した時からやっております。構造体のメンバーが変わるたびに、コメントにしたり、しなかったりするのが面倒なのでこの質問をしています。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- UNIX・Linux Linuxサーバーのパーティション・ディレクトリの推奨見積もりについて 3 2023/01/17 00:46
- C言語・C++・C# プログラムが書けません。 4 2023/01/22 22:57
- C言語・C++・C# C言語初心者 構造体 課題について 1 2023/03/10 19:30
- UNIX・Linux サーバー間のデータコピー(データ形式とデーターフォーマットの変換あり。一定間隔で処理) 2 2023/08/22 22:15
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- サーバー Webサイト構築フリーランスの案件受注について 1 2022/03/27 18:16
- ガラケー・PHS 22年前のガラケーの譲渡について 1 2022/07/03 22:27
- ネットワーク プロトコルの階層化とインターフェースとの違い 2 2022/07/26 02:38
- ネットワーク OSI参照モデルの各層の役割がわかりません。 3 2023/04/21 21:12
- C言語・C++・C# アセンブラ指令 3 2023/06/17 14:47
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBAで変数定義を変更する方法
-
ビット演算について
-
C++でデータの途中から読み込み
-
16進数のバイト数
-
FORTRANのCOMMONについて
-
#pragmaについて
-
Schemeのコンストラクタの引数は?
-
この型変換の内容がわかりませ...
-
errorC2228 CColorDialog
-
C++変数宣言時のコンストラクタ...
-
C言語のプログラムの流れについて
-
ExcelVBAで初期値のセット
-
メッセージキュー
-
デフォルトコンストラクタで分...
-
「 VBA の 宣言 」 がない場合...
-
変数の初期化について
-
整数から16進数への変換 現在c...
-
Pythonです。 monster ballを定...
-
VBAのプログラムで、DIAG = 1# ...
-
文字列の検索&排除をするプロ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAのプログラムで、DIAG = 1# ...
-
Integer変数をカラにしたいので...
-
「#undef」と「#define」の使い...
-
C言語 構造体の中に共用体を定...
-
構造体のデータを丸ごとコピー...
-
VBAの変数のデータ型を変更する...
-
日付チェック関数について
-
整数から16進数への変換 現在c...
-
typedefをプログラム中で解除す...
-
値が代入されてない時
-
C++ 構造体の一括初期化 {0}
-
VBAで符号無し整数
-
long型のデータをバイト型の配...
-
変数の初期化について
-
1バイトデータの読み出しについて
-
charとucharの違い
-
VBAにてcolorindexを変数に格納...
-
異なる構造体のデータのコピー
-
構造体を型の異なる構造体に代入
-
構造体にする理由・利点・使用例
おすすめ情報