开发游戏(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”的视图,然后递增指针+ = 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。
上面的链接显示了如何将其应用于偏移量的明确示例。
答案 0 :(得分:1)
MSDN中的示例应该适合您。 你可以找到它here
基本上在CreateFileMapping
您声明要分享的内存量,在MapViewOfFile
中您创建了一个&#39;视口&#39;在记忆中。它的尺寸可以等于或小于要求的数量。
现在可以读取或写入此内存。
在客户端,您可以使用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。
这不是处理文件映射的最有效方法,您需要考虑创建一个超级结构,其中包含可用条目数以及在结构末尾编码为VLA(可变长度数组)的条目:
typedef struct{
int nEntries; //Holds the number of entries
sJogo pS[];
} sGlobals;
sGlobals globals;