2015-08-26 4 views
0

У меня есть две программы win32, и они обмениваются данными с одной DLL через IPC. Я использую MSVC++, поэтому имеет смысл, что я использую CreateFileMapping и MapViewOfFile. У меня уже есть некоторые коды, проблема в том, что когда моя вторая программа запускается и загружает DLL и начинает работать с DLL, все в порядке, и связь IPC идет хорошо. Когда первая программа запускается и загружает DLL и начинает работать с DLL, а вторая запускает и загружает DLL и начинает работать с DLL, вторая программа перестает связываться с DLL через IPC. Связь IPC, вероятно, работает, но, вероятно, неправильно. Он получает размер и емкость, но содержимое нежелательно. Содержимое разделяемой памяти - вектор указателей! Что я делаю не так? Есть ли что-то, что мне нужно знать, чтобы заставить их работать нормально?IPC shared memory std :: vector в windows

//The sender writer 
MainWindow::~MainWindow() 
{ 
    UnmapViewOfFile(pBuf); 
    CloseHandle(hMapFile); 
} 

void MainWindow::SetData(vector <SubWindow*> &iMainWin) 
{ 
    hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(vector <SubWindow*>), TEXT("MyMappedMem")); 

    if (hMapFile == NULL) 
     return; 

    vector <SubWindow*> *pBuf = reinterpret_cast<std::vector<SubWindow*>*> (MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(vector <SubWindow*>))); 

    if (pBuf == NULL) 
    { 
     CloseHandle(hMapFile); 
     return; 
    } 

    memcpy(pBuf, &iMainWin, sizeof(iMainWin)); 
    return; 
} 

//The reciever reader 
void DataWork() 
{ 
    do{ 
     if (strcmp(pe32.szExeFile, "Win32Project.exe") == 0) 
     { 
      bProcessFound = true; 
      break; 
     } 
    } while (Process32Next(hProcessSnap, &pe32)); 

    if (!bProcessFound) 
    { 
     MessageBox(NULL, TEXT("ERROR Process32Next Openning DLL"), TEXT("ERROR"), MB_OK); 
     return; 
    } 
    else 
    { 
     HANDLE hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, TEXT("MyMappedMem")); 

     if (hMapFile == NULL) 
     { 
      MessageBox(NULL, TEXT("ERROR OpenFileMapping DLL"), TEXT("ERROR"), MB_OK); 
      return; 
     } 

     vector<SubWindow*> *pBuf = reinterpret_cast<std::vector<SubWindow*>*> (MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(vector <SubWindow*>))); 

     if (pBuf == NULL) 
     { 
      MessageBox(NULL, TEXT("ERROR MapViewOfFile DLL"), TEXT("ERROR"), MB_OK); 
      CloseHandle(hMapFile); 
      return; 
     } 

     for (int i = 0; i < buf->size(); i++) 
      (*buf)[i]->value_access; 

     UnmapViewOfFile(pBuf); 
     CloseHandle(hMapFile); 
    } 
} 
+0

Это неудобно неправильно. sizeof вашего вектора не совпадает с размером данных внутри этого вектора. Попробуйте вывести размер вектора 100 ints. Это будет примерно 20 байтов, см.? Вам нужно изменить способ сохранения данных в памяти. – grisha

+0

Скопление файлов, скорее всего, неправильное решение. Почему ты согласился на это? –

ответ

1

Указатели в первой программе бесполезны во второй программе, и наоборот. Вы не можете использовать указатель из программы A в программе B, потому что у них разные пространства виртуальной памяти.

1

Попытка разделить std::vector с использованием общей памяти почти наверняка неверна. std::vector будет выделять память из вызывающего процесса, который не будет доступен через какой-либо другой процесс. Кроме того, указатели, указывающие на локальные адреса, не будут доступны ни одному другому процессу.

Кроме того, вам необходимо будет координировать доступ к std::vector с использованием мьютекса, который вы не выполняете.

В этой ситуации я не вижу причин, по которым использование текстового файла было бы недостаточно.

+0

Текстовый файл, вероятно, является наихудшей идеей, когда вы хотите реализовать IPC. Кто собирается очистить мусор, который вы бросили на тротуар, например? Какие гарантии когерентности существуют? Как вы сигнализируете об изменениях? Как вы сигнализируете, когда безопасно использовать данные? Путь проще и удобнее: сериализовать данные и передать их по (названному) трубу. – IInspectable

+0

В примере не используется фактический IPC. Общая память и IPC в целом следует избегать, если это абсолютно необходимо. Однако да, есть другие механизмы, которые позволяют избежать сложности синхронизации доступа и дают лучшую семантику. – Jason

+0

Пример ** ** использует IPC. Он начинается с 'CreateFileMapping (INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof (вектор ), TEXT (« MyMappedMem »)) и получает переназначение в другой экземпляр того же модуля (в другом процессе). – IInspectable

Смежные вопросы