为何此处的Integer()强制转换在64位环境下是安全的?
关于Pascal代码中指针转Integer的安全性疑问
问题描述
这段代码来自一款适配32位与64位环境的第三方库,我默认此处的Integer()强制转换是安全的,但原因是什么?TDataModule的子类本质上是一个指针,Variant类型也并未让逻辑更清晰……
相关代码
type TROSession = class private protected function GetValues(const Name: string): Variant; virtual; procedure SetValues(const Name: string; const Value: Variant); virtual; public property Values[const Name: string]: Variant read GetValues write SetValues; default; end; procedure TDatamoduleServer.InMemorySessionManagerSessionCreated(const aSession: TROSession); var LDataModuleDataBase: TDataModuleDataBase; // a TDataModule descendant begin LDataModuleDatabase := TDataModuleDataBase.Create(nil); aSession.Values[SESSION_DMDATABASE] := Integer(LDataModuleDataBase);
解答
1. 指针转Integer的安全性原因
在Delphi及兼容的Pascal环境中,Integer类型的宽度会随目标平台自动适配:
- 32位平台下,
Integer为4字节,和指针宽度完全一致; - 64位平台下,
Integer被定义为8字节,同样匹配64位指针的宽度。
因此这里的Integer(LDataModuleDataBase)强制转换,本质是把指针值完整存入了一个宽度与指针完全匹配的整数类型中,不会出现截断或溢出问题,在32/64位环境下都能安全工作。
2. 为何用Variant存储?
TROSession.Values属性设计为Variant类型,是为了做通用存储容器——它可以容纳整数、字符串、对象指针等多种类型的数据,无需为每种数据类型单独设计属性或方法。虽然对于对象指针来说,用Variant确实不如强类型容器直观,但这是通用存储方案的取舍,第三方库选择这种设计是为了兼顾最大的灵活性。
后续需要取出指针时,只需反向转换即可安全还原对象实例:TDataModuleDataBase(Pointer(Integer(aSession.Values[SESSION_DMDATABASE])))。
内容的提问来源于stack exchange,提问作者Jan Doggen
相关产品推荐
相关产品推荐

