C++共有メモリによるプロセス間通信

7173 ワード

C++共有メモリを用いてプロセス間通信ファイルマッピングを実現することは、プロセス間の一方向または双方向通信を実現するメカニズムである.2つ以上のローカル・プロセス間で通信できます.ファイルまたはメモリを共有するには、すべてのプロセスが同じファイルマッピングの名前またはハンドルを使用する必要があります.共有ファイルを実装するには、最初のプロセスでCreateFileメソッドを呼び出します.次に、CreateFileMappingメソッドを呼び出してファイルマッピングオブジェクトを作成します.ファイルマッピングのハンドルと名前を指定します.イベント、信号、反発オブジェクト、ファイルマッピングなどのカーネルオブジェクトが同じ名前空間を共有しているため、この名前が他のオブジェクトの名前と重複すると作成に失敗します.共有メモリを実装するには、プロセスはまずCreateFileMapping関数を呼び出し、hFileパラメータからINVALID_に転送する必要があります.HANDLE_ハンドルの代わりにVALUEマクロを使用します.対応するファイルマッピングオブジェクトは、システムのページングファイルからメモリを取得します.hFileパラメータの値がINVALID_の場合HANDLE_VALUEでは、CreateFileMappingを呼び出すときに共有メモリにサイズ値を指定する必要があります.共有メモリまたはファイルを使用するプロセスでは、MapViewOfFile関数またはMapViewOfFileEx関数を使用してファイルビューを作成する必要があります.次に、「LocalSampleMap」という名前のファイルマッピングオブジェクトを作成し、文字列をファイルマッピングに書き込みます.サービスプログラムとクライアントプログラムの2つのプログラムを作成します.サービス・プログラムは、ファイル・マッピングの作成を担当します.サービスプログラムの名前はCppFileMappingServerで、その実行プロセスは1.特定のサイズのファイルマッピングオブジェクトを作成し、名前は「LocalSampleMap」2.このオブジェクトのファイルビューをプロセスのアドレス空間にマッピングし、ビューに文字列を書き込みます.
次に、クライアントプログラムCppFileMappingClientを実行します.まず、「LocalSampleMap」という名前のファイルマッピングオブジェクトを開きます.次に、同じファイルマッピングビューを自分のアドレス空間にマッピングします.次に、サービスプロセスから書き込まれたデータをビューから読み出す.
Serverフルソース:
#pragma region Includes  
#include <stdio.h>  
#include <windows.h>  
#pragma endregion  
#define MAP_PREFIX          L"Local\\"  
#define MAP_NAME            L"SampleMap"  
#define FULL_MAP_NAME       MAP_PREFIX MAP_NAME  
  
// Max size of the file mapping object.  
#define MAP_SIZE            65536  
  
// File offset where the view is to begin.  
#define VIEW_OFFSET         0  
  
// The number of bytes of a file mapping to map to the view. All bytes of the   
// view must be within the maximum size of the file mapping object (MAP_SIZE).   
// If VIEW_SIZE is 0, the mapping extends from the offset (VIEW_OFFSET) to    
// the end of the file mapping.  
#define VIEW_SIZE           1024  
  
// Unicode string message to be written to the mapped view. Its size in byte   
// must be less than the view size (VIEW_SIZE).  
#define MESSAGE             L"Message from the first process."  
  
  
int wmain(int argc, wchar_t* argv[])  
{  
    HANDLE hMapFile = NULL;  
    PVOID pView = NULL;  
  
    // Create the file mapping object.  
    hMapFile = CreateFileMapping(  
        INVALID_HANDLE_VALUE,   // Use paging file - shared memory  
        NULL,                   // Default security attributes  
        PAGE_READWRITE,         // Allow read and write access  
        0,                      // High-order DWORD of file mapping max size  
        MAP_SIZE,               // Low-order DWORD of file mapping max size  
        FULL_MAP_NAME           // Name of the file mapping object  
        );  
    if (hMapFile == NULL)   
    {  
        wprintf(L"CreateFileMapping failed w/err 0x%08lx
", GetLastError()); goto Cleanup; } wprintf(L"The file mapping (%s) is created
", FULL_MAP_NAME); // Map a view of the file mapping into the address space of the current // process. pView = MapViewOfFile( hMapFile, // Handle of the map object FILE_MAP_ALL_ACCESS, // Read and write access 0, // High-order DWORD of the file offset VIEW_OFFSET, // Low-order DWORD of the file offset VIEW_SIZE // The number of bytes to map to view ); if (pView == NULL) { wprintf(L"MapViewOfFile failed w/err 0x%08lx
", GetLastError()); goto Cleanup; } wprintf(L"The file view is mapped
"); // Prepare a message to be written to the view. PWSTR pszMessage = MESSAGE; DWORD cbMessage = (wcslen(pszMessage) + 1) * sizeof(*pszMessage); // Write the message to the view. memcpy_s(pView, VIEW_SIZE, pszMessage, cbMessage); wprintf(L"This message is written to the view:
\"%s\"
", pszMessage); // Wait to clean up resources and stop the process. wprintf(L"Press ENTER to clean up resources and quit"); getchar(); Cleanup: if (hMapFile) { if (pView) { // Unmap the file view. UnmapViewOfFile(pView); pView = NULL; } // Close the file mapping object. CloseHandle(hMapFile); hMapFile = NULL; } return 0; }

Clientフルソース
#pragma region Includes  
#include <stdio.h>  
#include <windows.h>  
#pragma endregion  
#define MAP_PREFIX          L"Local\\"  
#define MAP_NAME            L"SampleMap"  
#define FULL_MAP_NAME       MAP_PREFIX MAP_NAME  
  
// File offset where the view is to begin.  
#define VIEW_OFFSET         0  
  
// The number of bytes of a file mapping to map to the view. All bytes of the   
// view must be within the maximum size of the file mapping object. If   
// VIEW_SIZE is 0, the mapping extends from the offset (VIEW_OFFSET) to the   
// end of the file mapping.  
#define VIEW_SIZE           1024  
  
  
int wmain(int argc, wchar_t* argv[])  
{  
    HANDLE hMapFile = NULL;  
    PVOID pView = NULL;  
  
    // Try to open the named file mapping identified by the map name.  
    hMapFile = OpenFileMapping(  
        FILE_MAP_READ,          // Read access  
        FALSE,                  // Do not inherit the name  
        FULL_MAP_NAME           // File mapping name   
        );  
    if (hMapFile == NULL)   
    {  
        wprintf(L"OpenFileMapping failed w/err 0x%08lx
", GetLastError()); goto Cleanup; } wprintf(L"The file mapping (%s) is opened
", FULL_MAP_NAME); // Map a view of the file mapping into the address space of the current // process. pView = MapViewOfFile( hMapFile, // Handle of the map object FILE_MAP_READ, // Read access 0, // High-order DWORD of the file offset VIEW_OFFSET, // Low-order DWORD of the file offset VIEW_SIZE // The number of bytes to map to view ); if (pView == NULL) { wprintf(L"MapViewOfFile failed w/err 0x%08lx
", GetLastError()); goto Cleanup; } wprintf(L"The file view is mapped
"); // Read and display the content in view. wprintf(L"Read from the file mapping:
\"%s\"
", (PWSTR)pView); // Wait to clean up resources and stop the process. wprintf(L"Press ENTER to clean up resources and quit"); getchar(); Cleanup: if (hMapFile) { if (pView) { // Unmap the file view. UnmapViewOfFile(pView); pView = NULL; } // Close the file mapping object. CloseHandle(hMapFile); hMapFile = NULL; } return 0; }

実行効果:
Server
Client