のようなコンテナーにstd::string
キーと大きな値を入れる際のヒープと、値渡しと参照渡しのセマンティクスに少し混乱しています。struct
boost::interprocess::map
これが私の状況と、私が使用しているいくつかのtypedefです:
typedef std::string AreaKeyType;
typedef DATA_AREA_DESC AreaMappedType; // DATA_AREA_DESC is a big struct.
typedef std::pair<const AreaKeyType, AreaMappedType> AreaValueType;
typedef boost::interprocess::allocator<AreaValueType, boost::interprocess::managed_shared_memory::segment_manager> AreaShmemAllocator;
typedef boost::interprocess::map<AreaKeyType, AreaMappedType, std::less<AreaKeyType>, AreaShmemAllocator> AreaMap;
AreaValueType (std::pair の typedef) を挿入する方法は次のとおりです。
AreaValueType A(areaKey, arearec);
anAreaMap->insert(A);
上記のコードは、ローカル (非共有メモリ) スタックの std::pair である A を共有メモリ領域にコピーすると思います。boost::interprocess::map 内のその共有メモリ領域へのハンドルを取得できますか?それとも、そのレコード全体を取得して全体を保存することに制限されていますか? (つまり、構造体のようなものをブースト インタープロセス マップに格納してから、そのレコード内の 1 バイトを更新できますか、または DATA_AREA_DESC 構造体のすべてのバイトを完全に新しいものに置き換えて、レコード全体を更新するだけでよいですか?バイト)
さらなる説明:
内部で C++ と Boost::interprocess::map を使用するプレーンな古い ANSI C DLL エクスポート API があります。この関数は、マップ内にアイテムを作成し、ハンドルを返すことが期待されています。boost::interprocess::map に何かを挿入し、そのエンティティへのハンドルを非 C++ ユーザーに返すにはどうすればよいです
void*
かunsigned long
? 私ができることは、 std::string キー値を調べて共有メモリから何かをフェッチし、新しいレコードをメモリに書き込むことだけです。代わりに、共有メモリ オブジェクトへの参照を維持できるようにしたいと考えています。直接できない場合、間接的にはどうすればよいでしょうか。非共有メモリ std::vector を保持し、areaKey の値 (std::string) を保持する非共有メモリ std::string を割り当ててから、
void*
アイテムのキャストを実行できると思います。に戻りstd::string
、それを使用して共有メモリ領域からレコードをフェッチします。それはすべて、非常に基本的なものに厳密に必要な作業よりも多くの作業のように思えます. たぶん、boost::interprocess::map は私の要件にとって正しい選択ではないでしょうか?
私は何を試しましたか?これはコンパイルされますが、これを正しく行っているかどうかはわかりません。::iterator
どういうわけか、返された fromを逆参照しfind
、すぐに次のようにそのアドレスを取得するのが醜い気がします:
void ** handle; // actually a parameter in my api.
*handle = (void*)&(*anAreaMap->find(areaKey));
更新上記は機能します。ただし、以下の回答の非常に賢明なアドバイスは機能しません。boost::interprocess::string を使用すると、実行時に完全な失敗とクラッシュが発生します。Boost の作成者が std::string サポートをコーディングしない限り、std::string を使用する権利はありませんが、実際にはうまく機能します。