2010-04-15 6 views
1

Я использую учебник по адресу this MSDN link, чтобы реализовать способ передачи данных из одного процесса в другой. Хотя мне посоветовали в earlier question использовать методы Pipe, из-за определенных ограничений у меня нет выбора, кроме как использовать метод CreateFileMapping.Ошибка при использовании CreateFileMapping - C

Теперь я успешно выполнил два отдельных проекта в виде окна в одном решении и редактировал некоторые свойства обеих форм нагрузки в одно и то же время.

Кроме того, мне удалось реализовать код, указанный в примере MSDN, в первую (Producer) и вторую (Consumer) программу без каких-либо ошибок компиляции.

Проблема, с которой я столкнулся сейчас, - это когда я запускаю первую программу и пытаюсь создать дескриптор сопоставленного файла, мне дают ошибку, говоря, что это было неуспешно, и я не понимаю, почему это происходит.

Я добавил файлы кода Продюсера и Потребителя, чтобы продемонстрировать, что я пытаюсь сделать.

Производитель:

#include <windows.h> 
#include <stdio.h> 
#include <conio.h> 


//File header definitions 
#define IDM_FILE_ROLLDICE 1 
#define IDM_FILE_QUIT 2 
#define BUF_SIZE 256 

TCHAR szName[]=TEXT("Global\\MyFileMappingObject"); 
    TCHAR szMsg[]=TEXT("Message from first process!"); 

void AddMenus(HWND); 
LRESULT CALLBACK WindowFunc(HWND, UINT, WPARAM, LPARAM); 

////Standard windows stuff - omitted to save space. 

////////////////////// 
// WINDOWS FUNCTION // 
////////////////////// 
LRESULT CALLBACK WindowFunc(HWND hMainWindow, UINT message, 
          WPARAM wParam, LPARAM lParam) 
{ 
    WCHAR buffer[256]; 
    LPCTSTR pBuf; 

    struct DiceData storage; 
    HANDLE hMapFile; 

    switch(message)  
    { 
    case WM_CREATE: 
     { 

      // Create Menus 
      AddMenus(hMainWindow); 
     } 

     break; 
    case WM_COMMAND: 
     // Intercept menu choices 
     switch(LOWORD(wParam)) 
     { 
     case IDM_FILE_ROLLDICE: 
      { 
       //Roll dice and store results in variable 
       //storage = RollDice(); 

       ////Copy results to buffer 
       //swprintf(buffer,255,L"Dice 1: %d, Dice 2: %d",storage.dice1,storage.dice2); 

       ////Show via message box 
       //MessageBox(hMainWindow,buffer,L"Dice Result",MB_OK); 

       hMapFile = CreateFileMapping(
       (HANDLE)0xFFFFFFFF, // use paging file 
       NULL,     // default security 
       PAGE_READWRITE,   // read/write access 
       0,      // maximum object size (high-order DWORD) 
       BUF_SIZE,    // maximum object size (low-order DWORD) 
       szName);     // name of mapping object 

    if (hMapFile == NULL) 
    { 
     MessageBox(hMainWindow,L"Could not create file mapping object",L"Error",NULL); 
     return 1; 
    } 
    pBuf = (LPTSTR) MapViewOfFile(hMapFile, // handle to map object 
         FILE_MAP_ALL_ACCESS, // read/write permission 
         0,     
         0,     
         BUF_SIZE);   

    if (pBuf == NULL) 
    { 
     MessageBox(hMainWindow,L"Could not map view of file",L"Error",NULL); 

     CloseHandle(hMapFile); 

     return 1; 
    } 


    CopyMemory((PVOID)pBuf, szMsg, (_tcslen(szMsg) * sizeof(TCHAR))); 
    _getch(); 

    UnmapViewOfFile(pBuf); 

    CloseHandle(hMapFile); 

      } 
      break; 

     case IDM_FILE_QUIT: 
      SendMessage(hMainWindow, WM_CLOSE, 0, 0); 
      break; 
     } 
     break; 

    case WM_DESTROY: 
     PostQuitMessage(0); 
     break; 
    } 
    return DefWindowProc(hMainWindow, message, wParam, lParam); 
} 

// 
//Setup menus 
// 

Потребительские:

#include <windows.h> 
#include <stdio.h> 
#include <conio.h> 

//File header definitions 
#define IDM_FILE_QUIT 1 
#define IDM_FILE_POLL 2 

#define BUF_SIZE 256 
TCHAR szName[]=TEXT("Global\\MyFileMappingObject"); 


//Prototypes 
void AddMenus(HWND); 
LRESULT CALLBACK WindowFunc(HWND, UINT, WPARAM, LPARAM); 

//More standard windows creation, again omitted. 

////////////////////// 
// WINDOWS FUNCTION // 
////////////////////// 
LRESULT CALLBACK WindowFunc(HWND hMainWindow, UINT message, 
          WPARAM wParam, LPARAM lParam) 
{ 


    HANDLE hMapFile; 
    LPCTSTR pBuf; 

    switch(message)  
    { 
    case WM_CREATE: 
     { 

      // Create Menus 
      AddMenus(hMainWindow); 
      break; 
     } 

    case WM_COMMAND: 
     { 
      // Intercept menu choices 
      switch(LOWORD(wParam)) 
      { 
      case IDM_FILE_POLL: 
       { 
        hMapFile = OpenFileMapping(
         FILE_MAP_ALL_ACCESS, // read/write access 
         FALSE,     // do not inherit the name 
         szName);    // name of mapping object 

        if (hMapFile == NULL) 
        { 
         MessageBox(hMainWindow,L"Could not open file mapping object",L"Error",NULL); 
         return 1; 
        } 

        pBuf = (LPTSTR) MapViewOfFile(hMapFile, // handle to map object 
         FILE_MAP_ALL_ACCESS, // read/write permission 
         0,      
         0,      
         BUF_SIZE);     

        if (pBuf == NULL) 
        { 
         MessageBox(hMainWindow,L"Could not map view of file",L"Error",NULL); 

         CloseHandle(hMapFile); 

         return 1; 
        } 

        MessageBox(NULL, pBuf, TEXT("Process2"), MB_OK); 

        UnmapViewOfFile(pBuf); 

        CloseHandle(hMapFile); 

        break; 
       } 




      case IDM_FILE_QUIT: 
       SendMessage(hMainWindow, WM_CLOSE, 0, 0); 
       break; 
      } 
      break; 
     } 

    case WM_DESTROY: 
     { 
      PostQuitMessage(0); 
      break; 
     } 
    } 
    return DefWindowProc(hMainWindow, message, wParam, lParam); 
} 

// 
//Setup menus 
// 

Это не в коем случае не аккуратным и финал, но это только начало, спасибо за любую помощь.

Edit: Ошибка

Error Image

Edit2: Выходной

Output Image

+0

Один дополнительный вещь, чтобы наблюдать за: он выглядит как создает ваш продюсер отображение, отображение, запись, затем unmaps + closes. Объекты карты файлов существуют только тогда, когда некоторый процесс содержит для него открытый дескриптор, поэтому, как только производитель закрывает свой дескриптор, * poof! * - отображение исчезло, и не будет ничего, что может открыть пользователь. Для использования разделяемой памяти таким образом, по крайней мере один процесс должен долгое время удерживать память.Например, продюсер должен открыть и отобразить память в начале процесса, а затем распаковать/закрыть в конце процесса: таким образом он будет существовать всякий раз, когда клиент ищет его. – BrendanMcK

ответ

3

Ваш код для производителей работ для меня. Какую версию Windows вы используете? В более новых версиях (например, Vista и 7) существуют дополнительные ограничения безопасности при доступе к общей памяти. В статье MSDN вы упомянули об этом, отметив, что вы должны быть администратором для создания объектов глобальной общей памяти в Windows Vista/7.

Вы также должны позвонить в GetLastError(), чтобы узнать, какой код ошибки действительно возвращается из CreateFileMapping(), что может быть полезно при определении основной причины проблемы.

+0

Я использую Windows 7 на данный момент, с точки зрения просмотра GetLastError, могу ли я просто создать буфер, вызвать GetLastError и затем отобразить его в MessageBox? –

+0

GetLastError() просто возвращает код состояния DWORD (который вы можете найти в списке системных кодов ошибок в MSDN, чтобы найти сообщение). Вы можете либо отобразить его с помощью MessageBox, либо если у вас есть настроенный отладчик, вы можете просмотреть значение, пройдя через программу. – WildCrustacean

+0

Я пробовал использовать «FILE_MAP_ALL_ACCESS», но это не имеет никакого значения. –

1

В коде для производителя имеется _getch(), предназначенная для не консольного приложения?

+0

Хорошо заметили, не знаю, как это получилось. Я думаю, что образец, который я использовал, из статьи MSDN должен был использоваться с консольным приложением, и я должен забыть его удалить. –

0

Попробуйте изменить "Global \ MyFileMappingObject" в "MyFileMappingObject"

3

Обеспечить глобальное имя является уникальным; это можно сделать с помощью инструмента Process Explorer.

Если не уникально, это, как правило, не в состоянии с кодом ошибки 6 (недопустимый дескриптор) при вызове CreateFileMappinng

  1. Скачать Process Explorer из SysInternals
  2. Run Process Explorer
  3. Запустите приложение с точностью до точка останова перед ошибкой CreateFileMapping()
  4. Поиск MyFileMappingObject с помощью Find (Ctrl-F)
  5. Если что-то появилось, например, другое FileMap, Mutex и т. Д., Рассмотрите более уникальное имя и убедитесь, что ваше приложение не является его создающим.

Примечание: Рассмотрим именовании FileMapping с помощью GUID (Файл -> Инструменты> Создать GUID) в Visual Studio

1

Может быть, мы узнали из того же материала/примеры в прошлом. У меня была та же проблема, после перехода с XP на Windows 7:

NULL возврата ручки значения и GetLastError() = 5.

ERROR_ACCESS_DENIED 
    5 (0x5) 
    Access is denied. 

Система кодов ошибок (0-499): http://msdn.microsoft.com/en-us/library/ms681382.aspx

Я использовал lpName с обратными косыми чертами, как в примере Microsoft, с http://msdn.microsoft.com/en-us/library/windows/desktop/aa366537.aspx, который вы разместили выше. После изменения имени объекта сопоставления файлов (lpName) из «Global \ MyFileMappingObject» на «GlobalMyFileMappingObject» функция CreateFileMapping снова работает под Windows 7 без каких-либо изменений.

«Имя может быть„Global \“или„Local \“префикс явно создать объект в глобальном или пространству имен. Оставшаяся часть названия может содержать любые символы, кроме символа обратной косой черты ('\ '). Создание объекта сопоставления файлов в глобальном пространстве имен с сеанса, отличного от нуля сеанса, требует привилегии SeCreateGlobalPrivilege. Для получения дополнительной информации см. Раздел Kernel Object Namespaces ".

Это не просто смена имени! Если вам нужен доступ к глобальному пространству имен, вам нужно пойти по пути SeCreateGlobalPrivilege.

0

В операционной системе Windows 7 я нашел:

OpenFileMapping(FILE_MAP_ALL_ACCESS, ...); 

Причины проблем с:

CreateFileMapping(
       (HANDLE)0xFFFFFFFF, // use paging file 

Try:

OpenFileMappingA(SECTION_MAP_WRITE | SECTION_MAP_READ,...); 
Смежные вопросы