2011-07-12 4 views
-1

こんにちは私は正しく作成し、マップされたファイル(ウィンドウのためのmmap)process1があります。私はmmapとデータを書き込むことができますが、他のプロセスではデータを読むことができます。他の関数とのファイルマッピングへのアクセス

process1の別の機能でマップされたファイルにアクセスするときに問題があります。

私はこのようなマップファイルを作成:私はしません

int mancontrol(void* pvBrick, HANDLE hMutex, LPCSTR pBuf) 
{ 
    char Msg[256]; 
    string dataString = ""; 
    dataString = "AAAA en BBBB"; 
    strcpy(Msg, dataString.c_str()); 
    CopyMemory((PVOID)pBuf, Msg, strlen(Msg)); 
    dataString = ""; 

:私は、マップされたファイルをアクセスも、そこにデータを書き込みたい機能では

TCHAR szName[]=TEXT("Global\\MyFileMappingObject"); 

int mancontrol(void* pvBrick, HANDLE hMutex); 

int main() 
{ 
    //Handels and vars for IPC 
    HANDLE hMapFile; 
    LPCTSTR pBuf; 
    char szMsg[256]; 
    string dataStr = ""; 

    //Create file mapping 
    hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, BUF_SIZE, szName); 
    if (hMapFile == NULL) 
    { 
     printf("Failed to create a mmap \n"); 

     return 1; 
    } 

    //Map file(MapViewOfFile) and return pointer of the mapped file(file view) 
    pBuf = (LPTSTR) MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, BUF_SIZE); 
    if (pBuf == NULL) 
    { 
     printf("Failed to map mmap"); 
     CloseHandle(hMapFile); 

     return 1; 
    } 

は次のようになります新しいエラーを取得しますが、proces2はデータを読み取ることができません(メインでは、そこにprocess2が送信できるデータがあります)。関数内でマップされたファイルを開いて再度マップする必要がありますか?それとも、私の議論は間違っていますか?

答えて

1

私はバート・ジャンの推測が正しいと言います。

CreateFile()の最初のパラメータとして実際のファイルハンドルをCreateFileMapping()に渡すと、実際のディスクファイルにマッピングできます。マッピングされたファイルはそのまま残り、そのデータはアクセス可能なままです。

一方、一時メモリファイルを作成する最初のパラメータとしてINVALID_HANDLE_VALUEが渡されました。ファイルへのマッピングがないとすぐに、ファイルは消去されます。 2番目のプロセスがマッピングを作成すると、新しいファイルが作成されます。

実際には、2つのプロセスが長期間実行される可能性があるため、問題はない可能性があります。

ちょうど楽しみのために、私は簡単なサンプルプログラムをノックアップしました。プログラムがfmap.exeと呼ばれている場合(テスト版の場合)、1つのインスタンスを "fmap server"として、2番目のインスタンスを "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; 
    } 
} 
1

他のプロセスがマッピングにリンクする前に、メモリマッピングを作成するプロセスが終了したように見えます。この場合、Windowsがマッピングを削除しても驚かないでしょう。あなたのアプリケーションで時間内に物事はどのように整理されますか?

+0

私はミューテックスを省略していた、ミューテックスはMMAPを作成し、mancontrol機能の開口部befor解放されているか確認します。明日に私は完全なコードをポストウィル。私は今、それを取得カント。 フィードバックをお寄せいただきありがとうございます! – RSNL

関連する問題