2013-04-10 104 views
3

我有一段代码使用Delphi XE3编译为64位COM DLL。CopyMemory导致Win8上的访问冲突

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; 

在Win7-64bit上,以上工作正常。 但在Win8-64bit上,同一个DLL文件会在CopyMemory上抛出访问冲突。 CopyMemory是在WinAPI.windows单元中实现的。

就是这样。

procedure CopyMemory(Destination: Pointer; Source: Pointer; Length: NativeUInt); 
begin 
    Move(Source^, Destination^, Length); 
end; 

任何想法?谢谢。

+0

为什么u使用CopyMemory的,而不是标准的Pascal'Move'程序?或者,如果你不喜欢标准函数,那么来自http://FastCode.sf.net的优化函数呢? – 2013-04-10 15:55:53

+2

@ Arioch'The 32位编译器使用FastCode'Move',没有64位FastCode'Move'。 – 2013-04-10 15:58:02

+2

我不能说Doctorlai,@Arioch,但*我更喜欢'CopyMemory',因为我发现指针比无类型的引用参数更容易挖掘,并且我每天都以多种语言工作,所以拥有一个通用API是有帮助的。此外,由于API将所有内容直接转发给内置函数,所以任何人都可以选择。 – 2013-04-10 16:01:14

回答

7

此时:

Pointer(LongWord(Self.FMemory) + Self.FPosition) 

您截断一个64位指针为32位。因此访问冲突。相反,你需要

Pointer(NativeUInt(Self.FMemory) + Self.FPosition) 

你的代码是一样破Win7上,但不知何故,你是不吉利的,只有不断运行这个代码与地址< 4GB的指针。

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

+0

谢谢。很大的帮助。是。我刚刚意识到这个愚蠢的错误。我将为所有内存指针快速替换所有LongWord(x)到NativeUInt()。 – 2013-04-10 15:57:40

+0

留意我的建议并运行自上而下的分配测试。我相信你会发现更多的错误。 – 2013-04-10 15:58:37

+1

运行自上而下分配测试的具体情况如何? – 2013-04-10 16:04:05

4

David指出了你的问题的根源 - 你的指针类型转换对于64位是错误的。一个更好的解决方案是使用指针运算来代替,让编译器处理指针大小为您提供:

CopyMemory(
    @Buffer, 
    PByte(Self.FMemory) + Self.FPosition, 
    Result 
); 

或者:

Move(
    (PByte(Self.FMemory) + Self.FPosition)^, 
    Buffer, 
    Result 
); 
+0

谢谢..所以这个PByte的东西将需要{$ POINTERMATH ON}的技巧,对吧?两者都产生相同的代码,对吗? – 2013-04-10 21:19:41

+0

'POINTERMATH'只能通过'PByte'的RTL自动转为'ON',但需要手动转换为'ON'来处理任何其他需要使用指针运算的指针类型 – 2013-04-10 22:07:01

+0

我认为,由于历史事故,它也是'PAnsiChar'。 – 2013-04-10 22:43:07