gpt4 book ai didi

c - MapViewOfFile 偏移 - 如何使用它

转载 作者:太空宇宙 更新时间:2023-11-04 03:36:27 25 4
gpt4 key购买 nike

开发游戏(PT 中的“jogo”), 服务器最多可以同时运行 5 个游戏, 客户端将通过映射内存访问。

这就是我所拥有的:

服务器:

#define MAX_JOGOS 5
typedef struct{
...
} sJogo;

typedef struct{
sJogo * pS;
} sGlobals;

sJogo jogo[MAX_JOGOS]; //global
sGlobals globals[MAX_JOGOS]; //global
HANDLE hMapFile; //global

int _tmain(int argc, LPTSTR argv[]) {
...
hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(sJogo)*MAX_JOGOS, szName);
//create map for all games
....
}

//called when new game is created
void createView(int index){
//create view for 1 game and store pointer
//### need to apply offset here ###
globals.pS[index] = (sJogo * )MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(sJogo);
}

//called by thread on event set
void CopyJogo(int index){
//use stored pointer to update jogo
CopyMemory((PVOID)globals[index].pS, &jogo[index], sizeof(sJogo));
}

客户:

HANDLE hMapFile; //global
sJogo * pS; //global

int _tmain(int argc, LPTSTR argv[]) {
...
hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, szName);
pS = (sJogo *)MapViewOfFile(cdata.hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(sJogo));
//### need respective offset here ###
}

我尝试创建一个“sizeof(sJogo)*MAX_JOGOS” View ,然后递增 pointer+=sizeof(sJogo) * index;但是没有成功,所以现在我求助于你,你能帮我学习使用偏移量吗?

我坚持不懈地搜索并在 stackoverflow 上找到了一个很好的例子,但它是 C++,我无法适应它。

高阶 DWORD 偏移量的 sizeof(sJogo) 是否正确?但是我不知道什么是粒度,也不知道如何将它应用于低位 DWORD...

你能帮帮我吗?谢谢。


编辑:

下面的代码在 i = 1 (NULL) 时返回,我做错了什么?

int _tmain(int argc, LPTSTR argv[]) {
....
hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(sJogo)*MAX_JOGOS, szName);
if (hMapFile == NULL)
{...}

DWORD offset = 0;
for (i = 0; i < MAX_JOGOS; i++) {
if (MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, offset, sizeof(sJogo)) == NULL)
{
_tprintf(TEXT("Erro MapViewOfFile I: %d\n"), i);
CloseHandle(hMapFile);
return;
}
offset += sizeof(sJogo);
}
}

编辑 2:

解决了上面的问题,在这里找到了解决方案:

https://msdn.microsoft.com/en-us/library/windows/desktop/aa366548%28v=vs.85%29.aspx

我没有考虑偏移量的分配粒度,这导致 MapViewOfFile 在第二次尝试时返回 NULL。

上面的链接清楚地显示了如何将其应用于偏移量的示例。

最佳答案

MSDN 中的示例应该适合您。你可以找到它here

基本上,在 CreateFileMapping 中,您声明要共享的内存量,在 MapViewOfFile 中,您在内存上创建一个“视口(viewport)”。它的尺寸可以等于或小于请求的数量。

现在可以读取或写入此内存。

在客户端,您可以使用OpenFileMapping 打开映射,然后您应该映射您想要访问的内存数量,单个结构的大小。然后您可以迭代,同时 MapViewOfFile 返回一个有效地址以访问数组的所有元素:

sJogo *pS = NULL;
DWORD ofset = 0;
while((pS= (sJogo *)MapViewOfFile(cdata.hMapFile, FILE_MAP_ALL_ACCESS, 0, offset, sizeof(sJogo)))
{
//Do something with the current element pointed by pS

offset += sizeof(sJogo);
}

这里我们从映射内存中的零偏移量开始,然后根据结构的大小增加偏移量。这会将映射移动到结构数组的下一个元素。

当我们超过元素数量时,文件映射将返回 NULL。

这不是处理文件映射的最有效方法,您需要考虑创建一个包含可用条目数的 super 结构,以及在结构末尾编码为 VLA(可变长度数组)的条目:

typedef struct{
int nEntries; //Holds the number of entries
sJogo pS[];
} sGlobals;

sGlobals globals;

关于c - MapViewOfFile 偏移 - 如何使用它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32299112/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com