0

クライアント/サーバー アプリケーションでは、c++ オブジェクトを送受信する必要があります。派手なことをするために対応するクラスは必要ありませんが、最大のパフォーマンスが必要です (ネットワーク トラフィックと計算に関して)。そのため、単純にそれらをバイナリ文字列として転送することを考えました。基本的に私は次のことができるようにしたい

//Create original object
MyClass oldObj();

//save to char array
char* save = new char[sizeof(MyClass)];
memcpy(save, &oldObj, sizeof(MyClass));

//Somewhere of course there would be the transfer to the client/server

//Read back from char array
MyClass newObj();
memcpy(&newObj, save, sizeof(MyClass));

私の質問: これが機能するために、私のクラスは何を満たす必要がありますか? メンバーとしてのナチュラリーポインターは、別のアプリケーションに転送するときに機能しません。しかし、私のクラスが (c++03 および/または c++11 で) POD と見なされ、ポインターまたは同等のもの (STL コンテナーなど) をメンバーとして持たないことで十分でしょうか?

4

4 に答える 4

3

両方のマシンが次のことを行う必要があります。

  1. 同じエンディアンを持つ (int の場合)
  2. 同じ浮動小数点表現 (double)
  3. 全タイプ同一サイズです。
  4. 同じコンパイラ
  5. アプリケーションのビルドに使用されたものと同じフラグ。
  6. ポインターがうまく転送されません。

しかし、ネットワークはここで最も遅い部分になります.
ほとんどのオブジェクトをシリアル化するコストは、転送のコストと比較して無関係になります。もちろん、オブジェクトが大きくなればなるほどコストは高くなりますが、へこみができるようになるまでにはしばらく時間がかかります。

維持費が高くなることも考慮する必要があります。

于 2013-01-11T23:31:55.067 に答える
1

これが機能するために、私のクラスは何を満たす必要がありますか?

  • ポインターメンバーを持ってはいけません。すでに言及しています。
  • のように、サイズが実装定義のメンバーを持つことはできませんint
  • エンディアンが異なるため、整数メンバーを持つことはできません。
  • 表現が異なるため、浮動小数点メンバーを持つことはできません。
  • ...そしておそらくもっと!

基本的に、非常に制約のあるシナリオを除いて、それを行うことはできません。ネットワーク経由で安全に送信するには、プロトコルを選択し、データをそれに準拠させる必要があります。

パフォーマンスは、プロトコルに準拠するために値に必要な操作ではなく、ネットワークの速度と遅延によって制限されるため、大したことではありません。

于 2013-01-11T23:32:04.100 に答える
1

これが実行されるハードウェア/OS をどの程度制御できますか? 非常に移植性の高いコードを書いていますか、それとも [たとえば] 32 ビットおよび 64 ビットの x86 Windows でのみ実行されますか?

上記で説明したように、完全に「スーパーポータブル」にするために、「実装定義」サイズのオブジェクト (たとえば、16、18、32、36、または 64 ビットの int など) を使用することはできません。このようなアイテムは、定義された数と順序のバイトとして保存して、転送時に切断/再順序付けされないようにする必要があります。浮動小数点はさらに悪化する可能性があります...

多くの「超ポータブル」アプリケーションは、データをテキストとして保存します。少し遅くなりますが、テキストは、実行するアーキテクチャに関係なく単なるバイトのストリームであり、使用するマシンに関係なく同じように順序付けられるため、簡単に移植できます (0-9 に固執する限り、A- Za-z、!?<>、.()*& およびその他のいくつかの文字 - EBCDIC でエンコードされたマシンには注意してください。ただし、「ascii-to-ebcdic」変換を処理する傾向があります)。もう一方の端は、必要に応じてテキストを文字列/整数/浮動小数点数/倍精度浮動小数点数に変換するだけです。整数から数字の文字列への変換には、1 桁につき 1 つの除算が必要です (16 進数または base-36 を使用すると、多少は良くなりますが、人間が判読しにくくなります - 良いことも悪いこともあります)。これは、4 バイトを格納するより明らかに遅いです。他の欠点は、s (使用される値に応じて) 多くの場合、数値をバイナリとして保存するよりもテキストで保存する方が時間がかかります。そのため、ネットワーク パケットは少し大きくなります。これは、変換よりも大きな影響があります。プロセッサは、10Gbit ネットワーク カードで 1KB を送信するのにかかる時間内に多くの計算を行うことができるからです。そしてもちろん、1 つの数字 123456 と 3 つの 12、34、56 との違いを見分けることができるように、数バイト (スペース、コンマ、改行など) を追加する必要があります。[もちろん、" を使用する必要はありません。 、「それぞれの間]。そして、それが到着したら、相手側で全体を解析するためのコードが必要です。プロセッサは、10Gbit ネットワーク カードで 1KB を送信するのにかかる時間内に多くの計算を実行できるためです。そしてもちろん、1 つの数字 123456 と 3 つの 12、34、56 との違いを見分けることができるように、数バイト (スペース、コンマ、改行など) を追加する必要があります。[もちろん、" を使用する必要はありません。 、「それぞれの間]。そして、それが到着したら、相手側で全体を解析するためのコードが必要です。プロセッサは、10Gbit ネットワーク カードで 1KB を送信するのにかかる時間内に多くの計算を実行できるためです。そしてもちろん、1 つの数字 123456 と 3 つの 12、34、56 との違いを見分けることができるように、数バイト (スペース、コンマ、改行など) を追加する必要があります。[もちろん、" を使用する必要はありません。 、「それぞれの間]。そして、それが到着したら、相手側で全体を解析するためのコードが必要です。

システムが常に 32 ビット整数と IEEE-754 浮動小数点数を使用していることがわかっている場合 [これらは非常に一般的です!]、バイト オーダーを気にするだけで済むかもしれません。また、常に「x86」またはそのようなものになることがわかっている場合は、バイトオーダーについても心配する必要はありません. しかし、「私のコードを iPhone で実行するのは良い考えだ」と判断した場合、コードを変更する必要があるかもしれません。もちろん、それをiPhone側に任せて、残りが必要とするものに準拠させることもできます.

于 2013-01-12T00:09:18.220 に答える
-4

class他の回答では、この目的でa を使用する方法について言及されています。個人的には、struct代わりに a を使用することを好みます。C++ では、 astructは、 a と同様に、メンバー メソッド/演算子、コンストラクタ/デストラクタ、継承のサポートなどを持つことがclassできます。ただし、 aには明確に定義された予測可能なメモリ レイアウトがあり、コンパイラの暗黙的なパディングを追加/削除するステートメントをstruct介してそのレイアウトを明示的に整列させることができます (以前に a を整列しようとしたことはありませんが、サポートされていると思います)。アプリのプロセス外で交換する必要があるデータには、常に 8 ビット アラインを使用します。すべての意図と目的のために、最新のコンパイラでは、 aは基本的に a と同じです。そのメンバーのデフォルトの可視性は#pragmaclassstructstructclasspublicの代わりにprivate。しかし、私は別の目的のために保管structして分離するのが好きです. classAstructは、自由に操作したり、メモリ内で上書きしたりできるデータの単なる生のコンテナーです。 Aclassは、メモリ レイアウトとパディングがコンパイラによって定義されており、いじってはならないオブジェクトです。

于 2013-01-11T23:47:41.637 に答える