I've tried to implement a shared memory interface, however I am not able to get it working.
Since it isn't yet working I want to ask help. A shared memory is necessary for my application which is an Multiobjective Evolutionary Algorithm that runs on several processes, however the various processes need to exchange information, and instead of dumping it into a physical file a billion times, I'd rather share memory using this method.
I am on Win7x64 using C++ in VS v120. For the sake of testing, all of this code takes place in the same process until I've figured it out.
My filename is a const string
m_Filename = "Local\\shared_memory"
m_BufferSize = 1024
EDIT 1:
So I see there is some confusion as to what I am trying to do here, well I am confused as well. Looking at the official documentation from MSDN it uses the file mapping with INVALID_HANDLE_VALUE, and they don't seem to create a file on disk. This is fine for my solution. I don't need a file on disk, although either works. The reason I tried to do it the other way is because the first method failed and I started searching, and I came across threads on here where people say that they need to make the actual file as well.
This is a more complete code, and yes I do check the error codes.
The m_Filename is set in the class constructor. Buffer size is constant. I've removed my code which does the physical file stuff, I guess it isn't actually required?
void MemoryMapper::_CreateMappedFile() {
m_Handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
0, m_BufferSize, m_Filename.c_str());
if (m_Handle == NULL)
{
std::cout << m_DebugErrorTitle << "_CreateMappedFile(): " << MM_ERROR_CREATE_FAILED <<
" (" << GetLastError() << ")" << std::endl;
return;
}
m_pBuffer = (LPTSTR)MapViewOfFile(m_Handle, FILE_MAP_ALL_ACCESS, 0, 0, m_BufferSize);
if (m_pBuffer == NULL)
{
std::cout << m_DebugErrorTitle << "_CreateMappedFile(): " << MM_ERROR_MAPPING_FAILED <<
" (" << GetLastError() << ")" << std::endl;
CloseHandle(m_Handle);
return;
}
TCHAR szMsg[] = TEXT("Test message.");
CopyMemory((PVOID)m_pBuffer, szMsg, (_tcslen(szMsg) * sizeof(TCHAR)));
if (!UnmapViewOfFile(m_pBuffer)) {
std::cout << m_DebugErrorTitle << "_CreateMappedFile(): UnmapViewOfFile() returned false. (" << GetLastError() << ")" << std::endl;
}
if (!CloseHandle(m_Handle)) {
std::cout << m_DebugErrorTitle << "_CreateMappedFile(): CloseHandle() returned false. (" << GetLastError() << ")" << std::endl;
}
if (m_Debug > 1) { std::cout << m_DebugTitle << "Created mapped file: '" << m_Filename << "'." << std::endl; }
}
Running this code and I end up with the console message: [MemoryMapper] Created mapped file: 'Local\shared_memory'.
Then, in the same process, for the sake of testing?? I try to open the file again. This time I get error code 2 saying the file doesn't exist.
bool MemoryMapper::_Open(const std::string& fn) {
if (m_Debug > 2) { std::cout << m_DebugTitle << "Open '" << fn << "'." << std::endl; }
m_OpenHandle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, fn.c_str());
if (m_OpenHandle == NULL)
{
std::cout << m_DebugErrorTitle << " _Open('" << fn << "'): " << MM_ERROR_OPEN_FAILED << " (" << GetLastError() << ")" << std::endl;
m_IsOpen = false;
return m_IsOpen;
}
m_IsOpen = true;
if (m_Debug > 1) { std::cout << m_DebugTitle << "Open: " << std::to_string(m_IsOpen) << std::endl; }
return m_IsOpen;
}
The filename is the same. 100%.
Why can't I open the file?
Also, should I be checking if a shared memory object exists with the set filename before creating one? Does the object get cleared away when the application terminates?
EDIT 2:
It seems that the handle given from the initial CreateFileMapping() must remain open for the duration I want to use the shared object?
I attempted this and now it seems to work fine. I can make the object, open it, write and close it using separate calls. My mistake was closing the handle upon creation, although, which is correct?
file_handleas the first parameter toCreateFileMapping. - Johnny MoppCreateFileMapping()is returning NULL or not before you callOpenFileMapping(). If it does, then callGetLastError()to find out why, otherwise don't callGetLastError()at all, as you might get an error code from an earlier operation - Remy LebeauINVALID_HANDLE_VALUEas the first parameter ofCreateFileMapping(), then the mapping will be linked to a block of memory backed by the system paging file, not the file that was opened withCreateFile(). IOW, the contents of the file won't be shared with anyone who opens a handle to theLocal\shared_memorymapping. - Remy LebeauCreateFileMapping()can't reportERROR_FILE_NOT_FOUND, except MAYBE ifCreateFileMapping()succeeds and creates a new mapping that did not previous exist, but the result ofGetLastError()is undefined in that situation. The only error code that is valid on success isERROR_ALREADY_EXISTS. That goes back to my earlier comment: "Always check error codes, but ONLY when functions fail". Without a minimal reproducible example, we can't see how the OP is checking errors. - Remy Lebeau