1

私は次の構造を持っています:

struct outData{   
    int a;
    float lat, lon;
}

これは、共有メモリを介して IPC に使用されます。今、私はそれを次のように更新したいと思います:

    struct outData{
        int a;   
        std::vector<std::pair<std::string, int>> allInts;
        std::vector<std::pair<std::string, float>> allfloats;
}

私の共有メモリは利便性のために 4096 バイトの大きさなので、構造体を変更するたびにコードの sizeof(outData) 行を変更する必要はありません。

このような構造体を動的メンバーで作成すると、それらがすべて (int a) の後に作成され、したがって共有メモリ内に作成されることが保証されますか?

ベクトルのベクトルはどうですか?

    struct outData{
        int a;   
        std::vector<std::pair<std::string, int>> allInts;
        std::vector<std::pair<std::string, float>> allfloats;
        std::vector<std::pair<std::string, std::vector<byte>>> allByteMessages;
}

うわー、速い答えをありがとう!あなたの入力に基づいて、私はこの解決策を考え出しました:

struct outData{
    int *iarray;
    float *farray;
} gtempStruct; 

SetSharedMem(std::vector<std::pair<int, float>> &input)
{
    void * p_v;
    gtempStruct.iarray = new int[input.size()];
    gtempStruct.farray = new float[input.size()];
    fillStruct(input);
    outData *p_oD = (outData *) p_Shm; // p_Shm = pointer to shared memory start
    *p_oD = gtempStruct;
    p_v = p_oD;
    p_v = reinterpret_cast<char*>(p_v) + sizeof(outData) -1;
    p_v = reinterpret_cast<void*>(p_v);
    memcpy(p_v, gtempStruct.iarray, sizeof(int)*input.size())
    p_oD->iarray = (int*) p_v;
    .
    .
    .
}

これは機能しますが、十分にテストされていません。ありがとうございました!

4

4 に答える 4

2

これはうまくいきません。文字列は共有メモリにはありません。オブジェクトはそうなりますが、そのstd::string内容はそうではありません。についても同様ですstd::vector<byte>。ベクター オブジェクトは共有メモリにありますが、その内容はありません。

これらのクラスは両方とも、構築されたときに内容がどのくらい大きくなるかわかりません。そのため、静的コンテンツには、動的コンテンツを見つけるのに十分な情報が含まれています。動的コンテンツは個別に割り当てられます。

共有メモリを使用する場合は、その共有メモリの内容をバイト レベルで定義する必要があります。内部絶対ポインタを持つクラスは機能しません。ポインターが必要な場合は、プロセス間で意味を持つように、共有メモリ セグメントの開始点を基準にしてポインターを作成する必要があります。

于 2013-03-21T07:33:36.990 に答える
1

「それらがすべて(int a)の後に作成され、したがって共有メモリに作成されることが保証されている」とはどういう意味かわかりません。

ただし、shmemでは仮想テーブルを持つオブジェクト(少なくとも1つの仮想関数を持つオブジェクト)は使用できないと思います。これにより、そのような関数(たとえば、デストラクタ)が呼び出されたときにクラッシュが発生する可能性があります。

これは、アレイによって使用されるメモリが動的に割り当てられるという事実に追加されます。つまり、実際のアレイは別の場所にあります。

おそらく、次のようなカスタム構造を使用する必要があります。

struct {
    int arraySize;
    int array[];
}
于 2013-03-21T07:39:05.350 に答える
1

これはほとんど不可能ですが、それだけの価値はありません。

std::stringクラスとstd::vectorクラスは、データを自身の外部に、通常はnewで割り当てられたヒープに格納します。別のアロケータをテンプレートパラメータとして渡すことができます。その場合、newの代わりにそれが使用されます。理論的には、共有メモリを理解するアロケータを作成できます。信頼できるアロケータを書くのは難しいことに注意してください。

また、std構造体には内部ポインターがあります。共有メモリの仮想アドレスが2つのプロセスで異なる場合(おそらく)、それらのポインタはメモリの奇妙な部分に移動します。

単純な古いcスタイルの配列を構造体に入れることができ、それらはあなたが望むことをすることに注意してください。含めて、可変長の構造体を使用できます。ただし、c++のようなことをあまり行わない場合に限ります。

于 2013-03-21T07:41:07.147 に答える