更新-解决和回答,冒犯行已经被注释掉了。
简介
虽然我使用( CreateFile或GENERIC_WRITE)表示CreateFile,使用PAGE_READWRITE表示CreateFileMapping,但我在连接CreateFile时遇到了问题。
详细描述
我使用CreateFileMapping在进程之间共享内存。假设我没有映射到一个物理文件,而是使用INVALID_HANDLE_VALUE作为CreateFileMapping的第一个参数,那么实际的机制是很好的。这很好,不过我想要实现的是创建此映射的主进程使用基于磁盘的文件,并定期将其刷新到驱动器,并在其关闭时自动保存数据。
代码遵循.(当我运行此代码时,以ShowMessage的形式获得“错误5:访问被拒绝”)
const MaximumMapSize = 256 * 1024;
var virtualMemoryPath : string = '';
function getFileHandle(mapname : string; maxSize : dword) :THandle;
var diskfilename : string;
lpFileName: PChar;
dwDesiredAccess: DWORD;
dwShareMode: DWORD;
lpSecurityAttributes: PSecurityAttributes;
dwCreationDisposition : dword;
dwFlagsAndAttributes: DWORD;
hTemplateFile : THandle ;
temp : pointer;
begin
Result := INVALID_HANDLE_VALUE;
if (maxSize <= MaximumMapSize) and (Length(virtualMemoryPath) > 0) then
begin
diskfilename := virtualMemoryPath+mapname+'.bin';
if FileExists(diskfilename) then
Sysutils.DeleteFile(diskfilename);
lpFileName := PChar(diskfilename);
//dwDesiredAccess := GENERIC_WRITE or GENERIC_WRITE;//<<<wrong
dwDesiredAccess := GENERIC_READ or GENERIC_WRITE;
dwShareMode := 0;//FILE_SHARE_READ or FILE_SHARE_WRITE;//<<wrong
lpSecurityAttributes := nil;
dwCreationDisposition := CREATE_ALWAYS;
dwFlagsAndAttributes := 0;
hTemplateFile := 0 ;
Result := CreateFile(
lpFileName,
dwDesiredAccess,
dwShareMode,
lpSecurityAttributes,
dwCreationDisposition,
dwFlagsAndAttributes,
hTemplateFile);
if (Result <> INVALID_HANDLE_VALUE) then
begin
GetMem(temp,maxsize);
ZeroMemory(temp,maxsize);
FileWrite(result,temp^,maxSize);
FreeMem (temp,maxsize);
FlushFileBuffers(result);
SetFilePointer(result,0,0,FILE_BEGIN);
end;
end;
end;
function createMap (mapname : string ; maxSize: dword; var hFile: THandle) : THandle;
var
lpFileMappingAttributes: PSecurityAttributes;
flProtect : DWORD;
dwMaximumSizeHigh : DWORD;
dwMaximumSizeLow : DWORD;
lpName : PChar;
LastError : dword;
begin
Result := INVALID_HANDLE_VALUE;
if (maxSize > MaximumMapSize) then
exit;
// create a disk the file or return INVALID_HANDLE_VALUE if settings have not defined a path to folder
hFile := getFileHandle(mapname,maxSize);
lpFileMappingAttributes := nil;
flProtect := PAGE_READWRITE;
dwMaximumSizeHigh := 0;
dwMaximumSizeLow := maxSize;
lpName := PChar(mapname);
Result := CreateFileMapping(
hfile,
lpFileMappingAttributes,
flProtect,
dwMaximumSizeHigh,
dwMaximumSizeLow,
lpName);
if (Result = 0) then
begin
if (not (hFile = INVALID_HANDLE_VALUE) ) then
CloseHandle(hFile);
hFile := 0;
LastError := GetLastError();
ShowMessage( Format('Error %d : %s',[LastError,SysErrorMessage(LastError)]) );
end
else
begin
ShowMessage(Format('Returing handle %d',[result]));
if (hFile = INVALID_HANDLE_VALUE) then
hFile := 0;
end;
end;发布于 2013-04-15 14:26:56
错误就在这里:
GENERIC_WRITE or GENERIC_WRITE你的意思是:
GENERIC_READ or GENERIC_WRITE修复它,就可以创建您的文件映射。
我同意汉斯的意见,你不应该共享文件句柄。
发布于 2013-04-15 14:23:03
dwDesiredAccess := GENERIC_WRITE or GENERIC_WRITE;
dwShareMode := FILE_SHARE_READ or FILE_SHARE_WRITE;这行不通。你需要读写权限。此外,创建视图需要操作系统确保它是唯一可以写入文件的视图。除了通过视图,没有检测到写入文件的另一个进程的机制,并确保这样的写入在内存中以及时和同步的方式可见。特别是,在多个线程访问视图的情况下,不可能实现同步更新。
阅读共享也同样是不明智的,操作系统在从视图更新文件时没有提供任何保证。唯一的保证是在关闭所有视图时更新它。这也意味着有秩序地关闭Windows是必要的,你不能使这可靠的灾难,如停电。同样,读取需要通过视图完成,而不是文件。唯一合适的选择是不分享。
https://stackoverflow.com/questions/16017055
复制相似问题