无法启用Ada2012编译选项时,如何从System.address初始化类型?
解决方案:使用Ada 95/2005兼容的地址子句
你遇到的问题是因为with address =>是Ada 2012引入的Aspect Specification特性,而你的编译环境不支持该版本。在Ada 95及更早的标准中,可以通过变量地址子句来实现将变量绑定到指定System.Address的需求,无需修改编译选项。
修改后的完整代码
generic type T_Generic is private; package MyPackage is G_Addr : System.Address; procedure Register (myAddr : System.Address); procedure MyProcedure (myAddr : System.Address); end MyPackage; package body MyPackage is procedure Register(myAddr : System.Address) is begin G_Addr := myAddr; end Register; -- 修正原代码中的end语句错误 procedure MyProcedure (myAddr : System.Address) is myVar : T_Generic; -- 使用Ada 95兼容的地址子句绑定变量到指定地址 for myVar'Address use myAddr; begin if myAddr = G_Addr then -- 在这里操作myVar,它直接映射到myAddr指向的内存区域 null; end if; end MyProcedure; end MyPackage;
关键说明
- 地址子句语法:
for 变量名'Address use 目标地址;是Ada 95就支持的标准语法,用于显式指定变量的内存地址,功能和Ada 2012的with address =>完全一致,但兼容性更好。 - 内存安全性:需要确保
myAddr指向的内存区域的类型、大小与T_Generic完全匹配,否则会导致未定义行为(如内存访问错误、数据损坏)。 - 原代码修正:你的示例代码中
Register过程的结束语句错误地写为end MyProcedure;,已在修改后的代码中修正为end Register;,否则即使解决地址问题也无法编译。
备选方案:通过访问类型转换绑定地址
如果你更倾向于使用访问指针的方式,也可以通过System.Address_To_Access_Conversions包实现地址到访问类型的转换:
generic type T_Generic is private; package MyPackage is G_Addr : System.Address; procedure Register (myAddr : System.Address); procedure MyProcedure (myAddr : System.Address); end MyPackage; package body MyPackage is use System; -- 定义地址到访问类型的转换包 package Conv is new Address_To_Access_Conversions (T_Generic); type T_Generic_Access is access all T_Generic; procedure Register(myAddr : System.Address) is begin G_Addr := myAddr; end Register; procedure MyProcedure (myAddr : System.Address) is myVar : T_Generic_Access; begin myVar := T_Generic_Access (Conv.To_Pointer (myAddr)); if myAddr = G_Addr then -- 通过myVar.all操作目标内存区域的数据 null; end if; end MyProcedure; end MyPackage;
内容的提问来源于stack exchange,提问作者A.Pissicat
相关产品推荐
相关产品推荐

