Я бы сказал, что догадка Берт-Джана верна.
Вы можете выполнить сопоставление с файлом реального диска, передав реальный дескриптор файла из CreateFile () в качестве первого параметра CreateFileMapping (), затем сопоставленный файл сохраняется и его данные останутся доступными.
С другой стороны, вы передали INVALID_HANDLE_VALUE в качестве первого параметра, который создает временный файл памяти.Как только нет сопоставлений с файлом, он будет удален.Когда второй процесс создает отображение, он получает новый файл.
В реальной жизни два процесса могут работать дольше, поэтому это может не быть проблемой.
Ради интереса я запустил программу быстрого сэмпла.Если программа называется fmap.exe (как в моей тестовой версии), запустите один экземпляр как «fmap server», а второй как «fmap» (который является клиентом.
Введите текст в клиент ибудет распечатан сервером.
// fmap.cpp
#include <Windows.h>
#include <iostream>
#include <string>
#include <algorithm>
#include <stdexcept>
// convenience class to manage a mutex
class CMutex
{
public:
CMutex(const char *szName)
{
std::string sName = std::string("MUTEX_") + szName;
m_hMutex = ::CreateMutex(
NULL, // __in_opt LPSECURITY_ATTRIBUTES lpMutexAttributes,
FALSE, // __in BOOL bInitialOwner,
sName.c_str()); // __in_opt LPCTSTR lpName
if (!m_hMutex)
throw std::runtime_error("Failed to create mutex");
}
~CMutex()
{
if (m_hMutex)
::CloseHandle(m_hMutex);
}
void Lock()
{
::WaitForSingleObject(m_hMutex, INFINITE);
}
void Unlock()
{
::ReleaseMutex(m_hMutex);
}
private:
HANDLE m_hMutex;
};
// convenience class to lock a mutex and unlock it when it
// goes out of scope.
class CAutoLock
{
public:
CAutoLock(CMutex &m)
: m_mutex(m)
{
m_mutex.Lock();
}
~CAutoLock()
{
m_mutex.Unlock();
}
private:
CMutex &m_mutex;
};
// Class to manage a mapped file
// uses the same name for the file and the mutex
class CMappedFile
{
public:
CMappedFile(const char *szName)
: m_hMapFile(NULL)
, m_szBuff(NULL)
, m_mutex(szName)
{
m_hMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE, // HANDLE hFile,
NULL, // LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
PAGE_READWRITE, // DWORD flProtect,
0, // DWORD dwMaximumSizeHigh,
nBuffSize, // DWORD dwMaximumSizeLow,
szName); // LPCTSTR lpName
if (!m_hMapFile)
throw std::runtime_error("Failed to create mapping");
m_szBase =
reinterpret_cast<char *>(
MapViewOfFile(
m_hMapFile, // HANDLE hFileMappingObject,
FILE_MAP_ALL_ACCESS, // DWORD dwDesiredAccess,
0, // DWORD dwFileOffsetHigh,
0, // DWORD dwFileOffsetLow,
nBuffSize)); // DWORD dwNumberOfBytesToMap
if (!m_szBase)
throw std::runtime_error("Failed to create view");
// reserve first few bytes of the file for a length variable.
// The rest is the buffer.
m_szBuff = m_szBase + sizeof(size_t);
}
~CMappedFile()
{
if (m_szBase)
{
UnmapViewOfFile(m_szBase);
}
if (m_hMapFile)
{
CloseHandle(m_hMapFile);
}
}
// add a string to the mapped file
void Put(const std::string &sVal)
{
// lock mutex
CAutoLock l(m_mutex);
// create reference to beginning of the buffer
size_t &nLength = *reinterpret_cast<size_t *>(m_szBase);
// check for overflow
if (nLength + sVal.length() >= nBuffSize)
throw std::runtime_error("Buffer Overflow");
// copy string to buffer and increment length
std::copy(sVal.begin(), sVal.end(), m_szBuff + nLength);
nLength += sVal.length();
}
// read a string from the mapped file and
// clear the length field, indicating that
// this data has been read.
std::string Get()
{
// lock mutex
CAutoLock l(m_mutex);
// create reference to beginning of the buffer
size_t &nLength = *reinterpret_cast<size_t *>(m_szBase);
std::string sVal;
if (nLength)
{
// if anything is in the buffer read ot
sVal.assign(m_szBuff, nLength);
// reset length as we've read the buffer
nLength = 0;
}
return sVal;
}
private:
HANDLE m_hMapFile;
char * m_szBase;
char * m_szBuff;
CMutex m_mutex;
enum {
nBaseSize=1024, // whole file size
nBuffSize=nBaseSize-sizeof(size_t) // buffer size, after size has been reserved
};
};
void DoClient(CMappedFile &m);
void DoServer(CMappedFile &m);
int main(int argc, char* argv[])
{
try
{
const char szUniqueName[] = "CA249329_ACAE_11E0_9594_6CF0494804C2";
CMappedFile m(szUniqueName);
std::string sServer("server");
if (argc==2 && sServer==argv[1])
DoServer(m);
else
DoClient(m);
}
catch (std::exception &e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
void DoClient(CMappedFile &m)
{
std::cout << "Client running\n\n";
std::string s;
while (std::getline(std::cin, s))
m.Put(s);
}
void DoServer(CMappedFile &m)
{
std::cout << "Server running\n\n";
while (1)
{
std::string s = m.Get();
if (s.length())
std::cout << s << std::endl;
}
}