C ++从共享内存中读取

时间:2009-10-12 10:28:50

标签: c++ windows shared-memory

我想读取应用程序通过共享内存提供的状态信息。我想使用C ++来读取该命名共享内存的内容,然后使用来自C#类的pinvoke调用它。

从软件中我知道它有一定的文件结构:一个结构STATUS_DATA,其中包含四个SYSTEM_CHARACTERISTICS结构的数组。

我还不熟悉C ++,所以我试着基本上跟着msdn。为了找到要映射的文件的大小,我添加了struct成员的大小,以便在下面的代码中看到。这会导致ACCESS DENIED,因此我认为,基于结构的结果太高了。当我使用sizeof(STATUS_DATA)(我将结构添加到我的源代码中)时,它仍然以拒绝访问结束。如果我尝试更低的内容,比如1024字节,我在pbuf中看到的只有<,而在调试时。

这是我到目前为止所得到的:

#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <iostream>
#pragma comment(lib, "user32.lib")

using namespace std;


signed int BUF_SIZE = 4 * (10368 + 16 + 4 + 16 + 4 + 16 + 4 + 1 + 4); // sizeof(STATUS_DATA);
TCHAR szName[]=TEXT("ENGINE_STATUS");

int main()
{
   HANDLE hMapFile;
   unsigned char* pBuf;

   hMapFile = OpenFileMapping(
                   FILE_MAP_READ,    // read access
                   FALSE,                 // do not inherit the name
                   szName);               // name of mapping object 

   if (hMapFile == NULL) 
   { 
      _tprintf(TEXT("Could not open file mapping object (%d).\n"), 
             GetLastError());

      return 1;
   } 

   pBuf = (unsigned char*) MapViewOfFile(hMapFile, // handle to map object
               FILE_MAP_READ,  // read/write permission
               0,                    
               0,                    
               BUF_SIZE); // 1024);                  

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

   CloseHandle(hMapFile);
      return 1;
   }

   UnmapViewOfFile(pBuf);

   CloseHandle(hMapFile);

   return 0;
}

我还确保通过遵循hint这个共享内存“在那里”。有人可以给我一个暗示,我错过了什么?谢谢!

1 个答案:

答案 0 :(得分:3)

MapViewOfFile(dwNumberOfBytesToMap)的最后一个参数必须小于创建映射时指定的最大大小。因为我们不知道那个大小是多少,所以假设BUF_SIZE超过它而1024则不是这样,这似乎是公平的。为此参数指定0是将整个文件映射到单个视图的简单方法。

大多数(全部?)C ++调试器将假设指向char的指针是以空字符结尾的字符串,因此当您尝试查看映射数据时,它将仅显示为第一个字节为零。根据文件映射中的数据,这可能是第二个字节,这解释了为什么您没有看到太多信息。最好将返回的指针强制转换为STATUS_DATA *并查看各个成员。

简而言之:

  • 为dwNumberOfBytesToMap指定零(0)
  • 将返回的指针强制转换为STATUS_DATA *而不是unsigned char *