anahtar ve struct
büyük bir değerin boost::interprocess::map
gibi bir kaba yerleştirilmesiyle ilgili yığın ve by-value-göre-anlam semantiği tarafından biraz kafam karıştı. İşte Bir destek :: süreçler arası eşlemede saklanan bir değer öğesine geri dönüştürülebilen bir opak tutamacı (void * veya dword) nasıl döndürebilirim?
AreaValueType A(areaKey, arearec);
anAreaMap->insert(A);
: I (std için bir typedef :: çiftinin) AreaValueType takacağım nasıl
İşte
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;
olduğunu
Yukarıdaki kod kopyaları yerel (paylaşılmayan bellek) yığınımdaki bir std :: çifti olan bir paylaşılan bellek alanına kopyalar. Boost :: interprocess :: map içindeki paylaşımlı bellek alanına bir tutamaç alabilir miyim ya da bu kaydı geri almak ve tamamını saklamakla sınırlı mıyım? (Başka bir deyişle, bir yapı ara işlem haritasına bir yapı gibi bir şey kaydedebilir ve daha sonra bu kaydın içindeki tek bir baytı güncelleyebilir veya tüm kayıtların tümüyle yeni bir DATA_AREA_DESC yapısında yer değiştirerek tüm kaydı güncelleştirmek zorunda mıyım? bayt)
Bazı Daha fazla açıklamanın:.
içeriden C harflerini ++ ve Boost :: süreçler arası :: harita bir düz eski ANSI C DLL ihracat api var. Bu işlevin haritada bir öğe oluşturması ve ardından bir tanıtıcı döndürmesi beklenir. Boost :: interprocess :: haritasına bir şey nasıl ekleyebilirim ve daha sonra bu öğeye bir tanıtıcıyı C++ olmayan kullanıcılara, tercihen
void*
veyaunsigned long
'a dönüştürebilir miyim? Yapabileceğim tek şey, std :: string anahtar değerine bakarak paylaşılan belleğe bir şeyler almak ve belleğe yeni bir kayıt yazmak. Bunun yerine, paylaşılan bellek nesnesine bir referans tutabilmek isterim.Bunu doğrudan yapamazsam, dolaylı olarak nasıl yapabilirim? Paylaşımlı olmayan bir std :: vektörünü saklayabilirim ve paylaşılamayan bir bellek std :: string'i bir std :: string olan fieldKey değerini tutup, sonra da
void*
dökümünü yapabilirim Öğeyistd::string
'a geri döndürün ve sonra paylaşılan hafıza alanından bir kaydı almak için bunu kullanın. Her şey çok basit bir şey için kesinlikle gerekli olması gerekenden daha fazla iş gibi görünüyor. Belki destek :: interprocess :: harita gereksinimleri için doğru seçim değil mi?
Ne denedim? Bu, derler, ancak bu hakkı kullanıp kullanmadığımı hiç bilmiyorum. Her nasılsa ben hemen şöyle adresini alarak daha sonra bir ::iterator
find
döndü dereferencing ve iç çirkin hissediyorum:
void ** handle; // actually a parameter in my api.
*handle = (void*)&(*anAreaMap->find(areaKey));
Güncelleme yukarıdaki eserler. Aşağıdaki cevabın çok mantıklı tavsiyesi, ancak çalışmaz. Boost :: interprocess :: string kullanımı, tam ve toplam başarısızlıkla sonuçlanır ve çalışma zamanında kilitlenir. Boost kodlu std :: string desteğinin yazarları özellikle çalışmadığı sürece çalışma hakkı olmayan std :: string'in kullanılması gerçekten işe yarıyor. handle
paylaşılan hafızada std::pair
bir gösterici olması gerekiyordu Eğer
iyi, find() yerine at() kullanabilirsiniz, sonra dereferencing olmayacaktır :) – EHuhtala
Sanırım haklısınız. –