windows MapViewOfFile 在 32 位和 64 位进程之间共享
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2455146/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
MapViewOfFile shared between 32bit and 64bit processes
提问by MK.
I'm trying to use MapViewOfFile in a 64 bit process on a file that is already mapped to memory of another 32 bit process. It fails and gives me an "access denied" error. Is this a known Windows limitation or am I doing something wrong? Same code works fine with 2 32bit processes.
我正在尝试在 64 位进程中对已映射到另一个 32 位进程的内存的文件使用 MapViewOfFile。它失败并给我一个“访问被拒绝”错误。这是已知的 Windows 限制还是我做错了什么?相同的代码适用于 2 个 32 位进程。
The code sort of looks like this:
代码看起来像这样:
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);
回答by Jerry Coffin
When you call CreateFile in the 32-bit application, you're passing 0
for the sharing parameter, which means no sharing is allowed. Changing that to FILE_SHARE_READ | FiLE_SHARE_WRITE
would probably be a step in the right direction.
当您在 32 位应用程序中调用 CreateFile 时,您传递0
的是共享参数,这意味着不允许共享。将其更改为FILE_SHARE_READ | FiLE_SHARE_WRITE
可能是朝着正确方向迈出的一步。
Edit: I just whipped together a demo that works (at least for me):
编辑:我刚刚制作了一个有效的演示(至少对我而言):
#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;
}
Any combination of 32- or 64-bit executables seems to work fine.
32 位或 64 位可执行文件的任何组合似乎都可以正常工作。
Edit2: Note, however, that this is purely demo-level code. Just for example, the name of each shared object should normally contain a GUID-string to ensure against accidental collision with other programs. I've also skipped quite a bit of error checking, not to mention the minor detail that this code doesn't accomplish anything useful.
Edit2:但是请注意,这纯粹是演示级代码。例如,每个共享对象的名称通常应该包含一个 GUID 字符串,以确保不会与其他程序发生意外冲突。我还跳过了很多错误检查,更不用说这段代码没有完成任何有用的小细节。