首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CreateFileMapping在hFile中失败,而不是INVALID_HANDLE_VALUE

CreateFileMapping在hFile中失败,而不是INVALID_HANDLE_VALUE
EN

Stack Overflow用户
提问于 2013-04-15 13:56:26
回答 2查看 2.2K关注 0票数 1

更新-解决和回答,冒犯行已经被注释掉了。

简介

虽然我使用( CreateFile或GENERIC_WRITE)表示CreateFile,使用PAGE_READWRITE表示CreateFileMapping,但我在连接CreateFile时遇到了问题。

详细描述

我使用CreateFileMapping在进程之间共享内存。假设我没有映射到一个物理文件,而是使用INVALID_HANDLE_VALUE作为CreateFileMapping的第一个参数,那么实际的机制是很好的。这很好,不过我想要实现的是创建此映射的主进程使用基于磁盘的文件,并定期将其刷新到驱动器,并在其关闭时自动保存数据。

代码遵循.(当我运行此代码时,以ShowMessage的形式获得“错误5:访问被拒绝”)

代码语言:javascript
复制
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;
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-04-15 14:26:56

错误就在这里:

代码语言:javascript
复制
GENERIC_WRITE or GENERIC_WRITE

你的意思是:

代码语言:javascript
复制
GENERIC_READ or GENERIC_WRITE

修复它,就可以创建您的文件映射。

我同意汉斯的意见,你不应该共享文件句柄。

票数 3
EN

Stack Overflow用户

发布于 2013-04-15 14:23:03

代码语言:javascript
复制
        dwDesiredAccess         := GENERIC_WRITE or GENERIC_WRITE;
        dwShareMode             := FILE_SHARE_READ or FILE_SHARE_WRITE;

这行不通。你需要读写权限。此外,创建视图需要操作系统确保它是唯一可以写入文件的视图。除了通过视图,没有检测到写入文件的另一个进程的机制,并确保这样的写入在内存中以及时和同步的方式可见。特别是,在多个线程访问视图的情况下,不可能实现同步更新。

阅读共享也同样是不明智的,操作系统在从视图更新文件时没有提供任何保证。唯一的保证是在关闭所有视图时更新它。这也意味着有秩序地关闭Windows是必要的,你不能使这可靠的灾难,如停电。同样,读取需要通过视图完成,而不是文件。唯一合适的选择是不分享。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16017055

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档