2

IPC が必要なアプリケーションがあります... 名前付きパイプはとても使いやすいので、その方法だと思います。

とにかく、名前付きパイプを使用して動的メモリを処理する方法について質問があります。

次のようなクラスがあるとします。

class MyTestClass {
public:
    MyTestClass() { _data = new int(4); }

    int GetData() { return *_data; }
    int GetData2() { return _data2; }

private:
    int* _data;
    int _data2;
};

オブジェクトでいっぱいのバッファを作成MyTestClassしてパイプ経由で送信すると、宛先プロセスで_dataが明らかに失われ、ガベージが発生します。私が使用すべき戦略はありますか?単純なケースでは値型を使用できますが、多くの複雑なクラスではある種の動的メモリを使用する必要があり、ポインターが好きです。

または、代わりに共有メモリの使用を検討する必要がありますか? ありがとう

4

2 に答える 2

3

名前付きパイプと共有メモリの両方に同様の問題があります。送信側で構造体の内容を にシリアル化し、受信側で構造体を逆シリアル化する必要があります。

シリアル化プロセスは、名前付きパイプまたは共有メモリを使用しているかどうかにかかわらず、本質的に同じです。埋め込みポインター (_data や _data2 など) の場合、一貫した方法でポインターの内容をシリアル化する必要があります。

メモリ内での構造の配置方法と IPC の効率性に応じて、使用できるシリアライゼーション戦略は多数あります。または、DCE RPC を使用して、RPC マーシャリング コードに複雑さを処理させることもできます。

于 2009-09-08T02:40:34.223 に答える
1

名前付きパイプを介してデータを送信するには、送信側でデータをシリアル化 (またはマーシャリング) し、受信側でデータを逆シリアル化 (またはアンマーシャリング) する必要があります。

データ構造にバイトのコピーを単に書き込んでいるかのように、疑わしく聞こえます。これではどうにもなりません。割り当てられたデータをコピーするのではなく (データ構造の最初と最後のバイトの間に保存されるのではなく、まったく別の場所に保存されます)、ポインター ( _data) をあるマシン (またはプロセス) から別のマシンにコピーします。ローカルプロセスのメモリアドレスは、他のプロセスでは意味が保証されていません。

ワイヤ プロトコルを自分で定義します (絶望的な場合は、ASN.1 を参照してください。いいえ、考え直して、絶望的なものにしないでください)。これは、ワイヤを介した送信用のデータのレイアウトを定義します。次に、送信側と受信側 (またはシリアライザーとデシリアライザー) の関数を実装します。または、すでにこれを行っている他の誰かのコードを見つけてください。

また、エンディアンに対処することも忘れないでください。名前付きパイプを介してバイトが送信されるシーケンスを定義する必要があります。

たとえば、送信されるメッセージが、ネットワーク バイト オーダーの 4 バイトの符号なし整数で構成され、その後に続く構造の数を定義するように定義できます。各構造は、配列の 4 つの符号付き 4 バイト整数のシーケンスであり、その後に 1 つの符号付き整数が続きます。の 4 バイト整数_data2(これもネットワーク バイト オーダーで送信されます)。

IPC メカニズムとしての名前付きパイプの選択は、ほとんど重要ではないことに注意してください。(本質的に同じマシン上で)共有メモリを使用していない限り、エンディアンネスに対処する必要があり、共有メモリであってもシリアライゼーションに対処する必要があります。

于 2009-09-08T02:46:10.000 に答える