Delphi 7至Delphi XE5

朱诺·诺尔

我正在将基于Indy TCP组件的服务器从Delphi 7移植到XE5,以启用64位支持。现在,在完成所有移植并运行服务器之后,它在测试环境中运行良好。直到用户数超过400为止,它都可以正常工作。此后,它开始创建访问冲突错误。有时出错会导致我进入indy源文件,有时会指向CPU窗口。我无法查明我的源代码中产生错误的区域。

虽然这种访问冲突错误表示我正在访问一些尚未实例化的对象,但是当较少的用户在线且整个代码与Delphi 7代码完全相同时,为什么不生成该错误,为什么要在其中访问和释放对象就像我在Delphi 7中所做的一样。

我在某个地方读到了与指针转换相关的东西应该使用NativeInt而不是Integer / Cardinal,现在在我处理传入数据的代码中,代码看起来像这样

procedure TMyContext.AddToPacketBuffer(Buffer: Pointer; Size: Integer);
var
  DestPtr: Pointer;
begin
  if PacketBufferPtr + Size<65536 then
  begin
    DestPtr := Pointer(Cardinal(FPacketBuffer)+Cardinal(PacketBufferPtr));
    Move(Buffer^,DestPtr^,Size);
    PacketBufferPtr := PacketBufferPtr + Size;
  end
  else
  begin
  end;
end;
  • FPacketBuffer是在每个TMyContext类中声明的全局Pointer,并且PacketBufferPtr是在每个TMyContext类中声明的Integer变量

我应该在这里使用NativeInt而不是Cardinal吗?这可能是问题的根源吗?如果是的话,当用户数低于400时为什么不产生错误,所以我在本地环境中使用所有功能进行了测试,并且没有任何代码部分会产生错误。

谢谢

戴维·赫弗南

关于64位代码,您必须了解的是指针为64位宽。与指针为32位宽的32位代码相反。现在,原生整数类型IntegerCardinal总是32位宽。显然,您不能将所有64位值都适合32位类型。

您是正确的,该代码是64位以下的。将64位指针强制转换为32位整数可能会导致截断。如果地址适合您的32位类型,则该代码可能会起作用。如果必须执行此类转换,则需要转换为NativeIntNativeUInt并且除了更改强制类型转换外,您还需要声明任何将指针保存为NativeInt或的变量NativeUInt

当然,理想情况下,您应该努力完全避免此类转换。您可以通过不使用Integer变量at来存储指针来实现。将指针存储为指针,避免转换为整数,并且永远不会遭受指针截断错误。

就是说,的名称PacketBufferPtr极具误导性。它不是名称所暗示的指针。这是一个偏移量。它应命名为PacketBufferOffset似乎永远不会超过high(Integer)似乎Integer是一个合理的选择。但是,宣布它为绝对不会有伤害NativeUInt

因此,假设您将指针声明为PByte,将偏移量声明为NativeUInt则代码将这样编写:

var
  FPacketBuffer: PByte;
  PacketBufferOffset: NativeUInt;
....    
procedure TMyContext.AddToPacketBuffer(Buffer: Pointer; Size: Integer);
var
  DestPtr: PByte;
begin
  if PacketBufferOffset + Size<65536 then
  begin
    DestPtr := FPacketBuffer + PacketBufferOffset;
    Move(Buffer^, DestPtr^, Size);
    inc(PacketBufferOffset, Size);
  end
  else
  begin
  end;
end;

现在,代码中没有强制转换。

我建议您启用自上而下的内存分配作为调试辅助。这将清除更多此类错误。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Delphi XE5中对AdMob的支持

来自分类Dev

如何从Delphi XE5调用GetProcessAffinityMask

来自分类Dev

Delphi XE5中对AdMob的支持

来自分类Dev

delphi xe5安装包

来自分类Dev

Delphi XE5:SymGetSymFromAddrw错误

来自分类Dev

XE5,JNI-如何向Delphi XE5添加(安装)JNI支持

来自分类Dev

将Delphi XE5工作区更改为Delphi 7

来自分类Dev

如何从delphi XE5 firemonkey样式提取PNG?

来自分类Dev

EraNames在Delphi XE5中去了哪里?

来自分类Dev

更改TEdits Delphi Xe5焦点的正确方法

来自分类Dev

Delphi XE5 Acces Violation on app start

来自分类Dev

Delphi XE5 Upd1 ShowMessage生成AV

来自分类Dev

delphi xe5 StrToFloat故障将ThousandSeparator更改为“,”

来自分类Dev

Delphi XE5 Android。按下硬件后退按钮

来自分类Dev

Delphi XE5 Android。如何使用PowerManager.WakeLock?

来自分类Dev

发送电子邮件Delphi XE5

来自分类Dev

在Delphi XE5中使用Socket Recv方法

来自分类Dev

Delphi XE5中心android布局

来自分类Dev

删除XE5 Delphi中的Android选项菜单

来自分类Dev

如何使用Delphi XE5创建Android动态壁纸?

来自分类Dev

如何使用Delphi XE5扩展Android类

来自分类Dev

Delphi XE5 exec root命令转换

来自分类Dev

使用Delphi Xe5将JSON转换为StringList

来自分类Dev

Delphi XE5中的ShowMessage缩短了

来自分类Dev

Delphi XE5中的Android后台服务

来自分类Dev

应用程序图标卡住DELPHI XE5

来自分类Dev

在Delphi XE5中文件日期返回错误

来自分类Dev

Chromium和Delphi XE5 + WebRTC不起作用

来自分类Dev

如何使用delphi xe5扩展android类