I'm trying to write a wrapper class in C++ to give mutex synchronised interprocess access to a shared memory vector of strings. This is my first foray into boost::interprocess and allocators are proving something of a mystery.
Is anyone able to see why on compilation I get the error:
error C2512: 'boost::interprocess::allocator::allocator' : no appropriate default constructor available C:\Program Files (x86)\Boost\boost_1_53_0\boost\container\string.hpp
#ifndef SHARED_MEMORY_WRAPPER_H//if not defined already
#define SHARED_MEMORY_WRAPPER_H//then define it
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
using namespace boost::interprocess;
class SharedMemoryWrapper
{
public:
SharedMemoryWrapper(const std::string &name, bool server) : m_name(name), m_server(server)
{
if (server)
{
named_mutex::remove("named_mutex");
shared_memory_object::remove(m_name.c_str());
//Create shared memory
managed_shared_memory m_segment(create_only, m_name.c_str(), 10000);
//Create allocators
CharAllocator charallocator(m_segment.get_segment_manager());
StringAllocator stringallocator(m_segment.get_segment_manager());
//This string is in only in this process (the pointer pointing to the
//buffer that will hold the text is not in shared memory).
//But the buffer that will hold "this is my text" is allocated from
//shared memory
MyShmString mystring(charallocator);
mystring = "this is my text";
//This vector is fully constructed in shared memory. All pointers
//buffers are constructed in the same shared memory segment
//This vector can be safely accessed from other processes.
MyShmStringVector *sharedSegmentVector = m_segment.construct<MyShmStringVector>("sharedSegmentVector")(stringallocator);
sharedSegmentVector->push_back(mystring);
}
else
{
//Open the shared segment
managed_shared_memory m_segment(open_only, name.c_str());
//Find the vector using the c-string name and open it
MyShmStringVector *sharedSegmentVector = m_segment.find<MyShmStringVector>("sharedSegmentVector").first;
}
m_mutex = new named_mutex(open_or_create, "named_mutex");
}
~SharedMemoryWrapper()
{
if (m_server)
{
named_mutex::remove("named_mutex");
//Destroy the vector from the managed_shared_memory
m_segment->destroy_ptr(sharedSegmentVector);//This will free all strings that the vector contains
m_segment->destroy<MyShmStringVector>("sharedSegmentVector");//Destroy the vector
//Is it necessary to destroy the allocators here?
//Remove the managed_shared_memory; this may fail if the memory does not exist or is mapped or opened by another process
shared_memory_object::remove(m_name.c_str());
}
delete m_mutex;
delete m_segment;
}
//Writer
void push(const std::string & in)
{
scoped_lock<named_mutex> lock(*m_mutex);
MyShmString inStr = in.c_str();
sharedSegmentVector->push_back(inStr);
}
//Reader function yet to be coded. Needs to return a vector containing a subset range of elements from the shared-memory-vector.
private:
//Typedefs
typedef boost::interprocess::allocator<char, managed_shared_memory::segment_manager> CharAllocator;
typedef boost::interprocess::basic_string<char, std::char_traits<char>, CharAllocator> MyShmString;
typedef boost::interprocess::allocator<MyShmString, managed_shared_memory::segment_manager> StringAllocator;
typedef boost::interprocess::vector<MyShmString, StringAllocator> MyShmStringVector;
bool m_server;
std::string m_name;
managed_shared_memory *m_segment;
MyShmStringVector *sharedSegmentVector;
named_mutex *m_mutex;
};//class
#endif//header guard
With thanks,
Riskybiz