CopyMemory导致Win8上的访问冲突

jus*_*tyy 3 delphi 64-bit

我有一段代码使用Delphi XE3编译成64位COM DLL.

function TRPMFileReadStream.Read(var Buffer; const Count: Longint): Longint;
begin
  if ((Self.FPosition >= 0) and (Count > 0)) then
  begin
    Result := Self.FSize - Self.FPosition;
    if ((Result > 0) and (Result >= Count)) then
    begin
      if (Result > Count) then
      begin
        Result := Count;
      end;
      CopyMemory(
        Pointer(@Buffer),
        Pointer(LongWord(Self.FMemory) + Self.FPosition),
        Result
      );
      Inc(Self.FPosition, Result);
      Exit;
    end;
  end;
  Result := 0;
end;
Run Code Online (Sandbox Code Playgroud)

在Win7-64bit上,以上工作正常.但在Win8-64bit上,相同的DLL文件将在CopyMemory上抛出Access Violation.CopyMemory在WinAPI.windows单元中实现.

就是这样.

procedure CopyMemory(Destination: Pointer; Source: Pointer; Length: NativeUInt);
begin
  Move(Source^, Destination^, Length);
end;
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?谢谢.

Dav*_*nan 7

在此刻:

Pointer(LongWord(Self.FMemory) + Self.FPosition)
Run Code Online (Sandbox Code Playgroud)

您将64位指针截断为32位.因此访问违规.相反,你需要

Pointer(NativeUInt(Self.FMemory) + Self.FPosition)
Run Code Online (Sandbox Code Playgroud)

你的代码在Win7上也是如此,但不知怎的,你运气不好,只用地址<4GB的指针运行这段代码.

您应该运行一些自上而下的内存分配测试来清除任何其他此类错误.

  • @DoctorLai我拒绝了您的建议编辑.抱歉.我真的觉得不走运.不幸的是,虫子直到现在才显现出来.任何外出的代码都有bug.如果这个bug早先出现了,那么代码可能会丢失.也许您尚未发布此代码,但您知道我的意思. (2认同)