我试图在已经映射到另一个32位进程的内存的文件上使用64位进程中的MapViewOfFile。 它失败,并给我一个“访问被拒绝”的错误。 这是一个已知的Windows限制或我做错了什么? 相同的代码适用于2 32位进程。
代码sorting如下所示:
hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, szShmName); if (NULL == hMapFile) { /* failed to open - create new (this happens in the 32 bit app) */ SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle = FALSE; /* give access to members of administrators group */ BOOL success = ConvertStringSecurityDescriptorToSecurityDescriptor( "D:(A;OICI;GA;;;BA)", SDDL_REVISION_1, &(sa.lpSecurityDescriptor), NULL); HANDLE hShmFile = CreateFile(FILE_XXX_SHM, FILE_ALL_ACCESS, 0, &sa, OPEN_ALWAYS, 0, NULL); hMapFile = CreateFileMapping(hShmFile, &sa, PAGE_READWRITE, 0, SHM_SIZE, szShmName); CloseHandle(hShmFile); } // this one fails in 64 bit app pShm = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, SHM_SIZE);
当您在32位应用程序中调用CreateFile时,您将0
传递给共享参数,这意味着不允许共享。 将其更改为FILE_SHARE_READ | FiLE_SHARE_WRITE
FILE_SHARE_READ | FiLE_SHARE_WRITE
可能是朝着正确方向迈出的一步。
编辑:我刚刚在一起演示了一个演示(至少对我来说):
#include <windows.h> #include <iostream> static const char map_name[] = "FileMapping1"; static const char event1_name[] = "EventName1"; static const char event2_name[] = "EventName2"; int main() { HANDLE mapping = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, map_name); if (NULL == mapping) { std::cout << "Calling CreateFile\n"; HANDLE file = CreateFile("MappedFile", FILE_ALL_ACCESS, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, 0, NULL); std::cout << "Creating File mapping\n"; mapping = CreateFileMapping(file, NULL, PAGE_READWRITE, 0, 65536, map_name); std::cout << "Closing file handle\n"; CloseHandle(file); } std::cout << "Mapping view of file\n"; char *memory = (char *)MapViewOfFile(mapping, FILE_MAP_ALL_ACCESS, 0, 0, 65536); if (memory == NULL) { std::cerr << "Mapping Failed.\n"; return 1; } std::cout << "Mapping succeeded\n"; HANDLE event = CreateEvent(NULL, false, false, event1_name); if (GetLastError()==ERROR_ALREADY_EXISTS) { std::cout <<"Waiting to receive string:\n"; WaitForSingleObject(event, INFINITE); std::cout << "Received: " << memory; HANDLE event2 = CreateEvent(NULL, false, false, event2_name); SetEvent(event2); } else { char string[] = "This is the shared string"; std::cout << "Sending string: " << string << "\n"; strncpy(memory, string, sizeof(string)); SetEvent(event); HANDLE event2 = CreateEvent(NULL, false, false, event2_name); WaitForSingleObject(event2, INFINITE); } return 0; }
32位或64位可执行文件的任何组合似乎都可以正常工作。
编辑2:但是,请注意,这是纯粹的演示级代码。 举例来说,每个共享对象的名称通常应包含一个GUID字符串,以确保不会与其他程序发生意外冲突。 我也跳过了一些错误检查,更不用说这个代码没有完成任何有用的细节。