Delphi11迁移Delphi10.3的unrar64.dll项目,RARSetCallback触发访问冲突
问题分析与解决方案
核心原因:64位编译下的数据类型不匹配
从Delphi 10.3升级到11后触发访问冲突,本质是64位环境下类型长度不兼容,具体涉及两个关键问题:
- UserData参数截断:你调用
RARSetCallback时用Integer(Self)转换对象指针,在64位Delphi中Self是8字节指针,而Integer是32位类型,强制转换会截断高32位数据,导致回调中拿到的UserData是错误地址,访问时触发内存冲突。 - 回调参数类型不匹配:原定义里的
longint是32位整数,但unrar64.dll是64位版本,对应的参数需要是64位类型,32位类型会破坏栈帧对齐,引发访问异常。
修正后的类型定义
将所有涉及指针/跨平台整数的类型替换为Delphi的NativeInt(该类型在32位编译时为4字节,64位时为8字节,自动适配平台):
// 修正后的回调函数类型 TRARUnRarCallBack = function(msg: Cardinal; UserData: NativeInt; P1: NativeInt; P2: NativeInt): Integer; stdcall; // 修正后的RARSetCallback过程定义 TRARSetCallback = procedure(hArcData: THandle; Callback: TRARUnRarCallback; UserData: NativeInt); stdcall;
调用代码修正
调用时直接传递对象指针的64位兼容类型,无需截断:
RARSetCallback(RARArchiveInstance, HandleRarCallBack, NativeInt(Self));
额外检查项
- 确保Delphi 11项目的编译目标为64位,unrar64.dll仅支持64位程序调用,32位程序调用会引发内存错误。
- 检查
HandleRarCallBack的实现,确保所有参数(如P1/P2)的处理都适配64位类型,避免将指针强制转换为32位整数使用。
内容的提问来源于stack exchange,提问作者Richard Fragiacomo
相关产品推荐
相关产品推荐

