共享内存 - 矩阵映射

时间:2015-05-16 00:59:31

标签: c++ winapi shared-memory

我目前正在开展一个Bomberman游戏项目,其中应该有一个具有二维矩阵的服务器,以及一个或多个客户端。

我认为应该这样做的方式是在进程之间使用共享内存,客户端和"敌人"访问以获取有关表格映射(矩阵)的信息并使用它。

问题在于我不知道如何将指针映射到我的Map对象(Matrix),以便其他进程可以获取该信息。

我从MSDN获得了这个功能,但我只解释了一个字符串:

   //Server.cpp

   //object creation (Matrix)
   Mapa M(height, width);

  hMapFile = CreateFileMapping(
             INVALID_HANDLE_VALUE,    // 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)
{
     _tprintf(TEXT("Could not create file mapping object (%d).\n"),
      GetLastError());

  return 1;
}

**HANDLE hMapFile = &M; // will this work?**

pBuf = (LPTSTR) MapViewOfFile(hMapFile,   // <- How can I pass the object here?
                    FILE_MAP_ALL_ACCESS, // read/write permission
                    0,
                    0,
                    BUF_SIZE);

if (pBuf == NULL)
{
       _tprintf(TEXT("Could not map view of file (%d).\n"),
       GetLastError());

   CloseHandle(hMapFile);

  return 1;

}

请问如何将指针映射到对象甚至是对象,以便其他进程可以访问?

此致

RC

1 个答案:

答案 0 :(得分:2)

要使用映射文件,您的服务器代码应如下所示。请注意,我不检查任何错误以保持发布的代码简单(始终检查错误!)。

/* server */
HANDLE hFile;
HANDLE hMapFile;

hFile = CreateFile("test.dat",
                   GENERIC_READ | GENERIC_WRITE,
                   0,
                   NULL,
                   OPEN_EXISTING,
                   FILE_ATTRIBUTE_NORMAL,
                   NULL);
hMapFile = CreateFileMapping(hFile,
                             NULL,
                             PAGE_READWRITE,
                             0,
                             1024 * 1024,
                             "test.mapping");   // "mapping file name" of "test.dat"

/* keep server process running and do not close hFile or hMapFile */

您的客户应该看起来像这样:

/* client */
HANDLE hMapFile;
char *pFile;   // note: you can use any type of pointer here!

hMapFile = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE,
                           FALSE,
                           "test.mapping");   // same name as within CreateFileMapping(..)
if (hMapFile != NULL)
{
    pFile = MapViewOfFile(hMapFile,
                          FILE_MAP_ALL_ACCESS,
                          0,
                          0,
                          1024 * 1024);

    /* read pFile */
    printf(pFile);

    /* write pFile */        
    wsprintf(pFile, "Hallo?");   // <-- writes to test.dat!!
}

如前所述,如果用于服务器/客户端架构,此设计将存在一些缺点。我建议使用TCP / IP服务器/客户端,它不比命名管道更难实现。一个好的起点是Running the Winsock Client and Server Code Sample,但网上有很多其他的例子......

如果使用TCP / IP,您的应用程序将如下所示:

/* server */

// create listener socket

// while running

   // accept new client(s)

   // receive data from clients (if any data was received)

   // react on data: (client sent 0x01 -> send matrix, ...)



/* client */

// create socket and connect to server

// send 0x01 command to obtain matrix

// receive response from server (= get matrix)

// do whatever your client does...

请注意,0x01是一个简单的命令字节,用于告诉服务器要做什么。您完全可以自由地告诉服务器该做什么。你也可以实现一个基于字符串的命令接口(例如客户端发送&#34; get_matrix&#34;而不是0x01)......