我想读取应用程序通过共享内存提供的状态信息。我想使用 C++ 来读取该命名共享内存的内容,然后使用 C# 类中的 pinvoke 调用它。
从软件上我知道它有一定的文件结构:A struct STATUS_DATA
具有四个结构的数组 SYSTEM_CHARACTERISTICS
.
我(还)不熟悉 C++,所以我尝试基本上遵循 msdn。为了找到要映射的文件的大小,我添加了结构成员的大小,如下面的代码所示。这导致访问被拒绝,所以我认为基于结构的结果太高了。当我使用 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 来确保此共享内存“存在” .有人可以给我一个提示,我错过了什么吗?谢谢!
最佳答案
MapViewOfFile (dwNumberOfBytesToMap) 的最后一个参数必须小于创建映射时指定的最大大小。由于我们不知道该大小是多少,因此假设 BUF_SIZE 超过它而 1024 没有超过它似乎是公平的。将此参数指定为 0 是将整个文件映射到单个 View 的简单方法。
大多数(全部?)C++ 调试器会假定指向 char 的指针是一个以 null 结尾的字符串,因此当您尝试查看映射数据时,它只会显示到第一个为零的字节。根据文件映射中的数据,这很可能是第二个字节,这解释了为什么您看不到太多信息。您最好将返回的指针转换为 STATUS_DATA* 并查看各个成员。
简而言之:
- 为 dwNumberOfBytesToMap 指定零 (0)
- 将返回的指针转换为 STATUS_DATA* 而不是 unsigned char*
关于C++ 从共享内存读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1553817/