Проблема столкнулась:
Общий список с использованием сопоставления файлов не предоставляет никаких данных внутри списка …
У меня есть процесс 1, в котором я сохраняю все свои данные в виде списка hash_map, а затем я пытаюсь поделиться этим с помощью сопоставления файлов … в Process2, пока я пытаюсь получить данные из списка, внутри списка не найдено данных ..
PS: мой exe в комплекте с dll, я делаю dll как process1 и exe как process2 …
Вот мой код,
Process1
/* this is in common headerFile */
typedef hash_map <std::wstring,std::wstring> AttrValues;
CString FileName = L"E:\\DataLog.txt";
TCHAR szName [] = TEXT («Local \ MyFileMappingObject»);
struct ADstruct
{
std::list<AttrValues> StList;
int i;
};/*Sharememory.cpp*/
DWORD SharedMemory()
{
AttrValues HardCode;//Sample data which i am hard coding for testing
HardCode[L"NAme"] = L"Test";
HardCode[L"D.Name"] = L"SAP";
std::list <AttrValues> HardCodedList;
HardCodedList.push_back(HardCode);
ADstruct CheckStruct;
CheckStruct.i = 10;
CheckStruct.StList = HardCodedList;
HANDLE hFile = INVALID_HANDLE_VALUE;// HANDLE hFile;
hFile = CreateFile(FileName.GetBuffer(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, 0, NULL);
if(hFile == INVALID_HANDLE_VALUE)
{
printf("Error in creating a file..!");
return 0;
}
hMapFile = CreateFileMapping(
hFile, // use paging file
NULL, // default security
PAGE_READWRITE, // read/write access
0, // maximum object size (high-order DWORD)
sizeof(ADstruct), // maximum object size (low-order DWORD)
szName); // name of mapping object
if (hMapFile == NULL)
{
_tprintf(TEXT("Could not create file mapping object (%d).\n"),
GetLastError());
return 1;
}
ADstruct *ADobj = new ADstruct;ADobj = (ADstruct *) MapViewOfFile(hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
sizeof(ADstruct) );CopyMemory( (ADstruct *) ADobj, &CheckStruct , sizeof(ADstruct) );
UnmapViewOfFile(pBuf);
CloseHandle(hMapFile);
return 0
}
Процесс 2:
BOOL ReadMemoryMapping()
{
hash_map<LPWSTR,LPWSTR> ADdata;
HANDLE hMapFile;
HANDLE hFile = INVALID_HANDLE_VALUE;
hMapFile = OpenFileMapping(
FILE_MAP_ALL_ACCESS, // read/write access
FALSE, // do not inherit the name
szName); // name of mapping object
if (hMapFile == NULL)
{
_tprintf(TEXT("Could not open file mapping object (%d).\n"),
GetLastError());
return 1;
}
ADstruct * readstruct;
readstruct = (ADstruct *) MapViewOfFile(hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
sizeof(ADstruct));
_tprintf(L"\nprint data%d\n",readstruct->i);
AttrValues At ;
for(std::list<AttrValues>::iterator list_iter = readstruct->StList.begin();
list_iter != readstruct->StList.end(); list_iter++)
{
At.clear();
At = *list_iter; //*****Here the code crashes as there is no datas inside***
if(At.empty() == 1)
printf("List is empty\n");
std::wcout<<endl<<endl<<"Attribute List In EXE : StList"<<endl;
for(AttrValues :: iterator it1 = list_iter->begin(); it1!= list_iter->end(); it1++)
{
std::wcout<<it1->first<<endl;
std::wcout<<it1->second<<endl;
}
}
UnmapViewOfFile(readstruct);
CloseHandle(hMapFile);
return 0;
}
Во-первых, регулярный std::list
является многоуровневой структурой данных, которая содержит ссылки на другие местоположения в адресном пространстве. Фактические элементы списка не хранятся внутри std::list
объект. Они хранятся в другом месте в памяти. А также std::list
просто ссылается на эти элементы через указатели. Ваше сопоставление файлов просто разделяет верхний уровень std::list
объект, но он даже не пытается поделиться фактическими элементами списка.
Во-вторых, даже если вам каким-то образом удастся волшебным образом определить и разделить всю область адресного пространства, которая содержит все, что связано с вашим std::list
это все равно не будет работать, если только вы не убедитесь, что во всех процессах эта память отображается в одну и ту же область в адресном пространстве. Это относится к любой структуре данных, которая использует указатели.
Другими словами, это не может быть сделано. Вы не можете просто взять существующую равнину std::list
и поделиться им через отображение памяти.
На самом деле, ваши попытки скопировать нетривиальный объект (например, std::list
) с помощью таких функций, как CopyMemory
может быть уже достаточно, чтобы разрушить целостность объекта. Нет необходимости задействовать отображения памяти.
Это возможно для вас, чтобы измениться. Стандартный шаблон библиотеки:
template<class T, class Allocator = std::allocator<T> > class list;
Таким образом, вы можете предоставить свой собственный распределитель памяти, если хотите, в качестве второго параметра шаблона. Если вы используете по умолчанию, который в основном new
, он будет выделять узлы из кучи, которых не будет в общей памяти. (Похоже, именно так вы используете файл с отображением в памяти.) Другой процесс сможет прочитать заголовок каждого списка, но не остальные узлы, расположенные где угодно.
Вместо этого вы могли бы, однако, выделить пул узлов в разделяемой памяти и написать свой собственный распределитель, который раздавал куски этой разделяемой памяти, пока она не исчезла. (Если каждый блок совместно используемой памяти можно использовать повторно, совместно используемая память может иметь свою собственную мини-кучу. Если вы можете просто удалить все списки одновременно, когда вы закончите с ними, этого будет достаточно, чтобы удалить карту блок разделяемой памяти.)
Или вы можете написать свой собственный класс списка, который использует индексы в пуле узлов в разделяемой памяти, а не в указателях, что является макетом, который на самом деле имеет смысл хранить в файле. Или вы могли бы выделить std::array
статически в разделяемой памяти. Все его хранилище находится внутри самого объекта класса и имеет фиксированный размер, поэтому он не выделяет никакой памяти за пределами общего блока и будет работать «из коробки».