如何解决Ada访问静态地址的不受限制的类型
以下是非法的Ada:
type Byte_Array is array (Natural range <>) of Interfaces.Unsigned_8;
type Byte_Array_Access is access all Byte_Array;
bytes : aliased Byte_Array(0 .. 9999);
for bytes'Address use To_Address(16#0040_0000#);
bytes_Access : Byte_Array_Access := bytes'Access;
编译器产生错误:
object subtype must statically match designated subtype
在最后一行。我所见的解决方法是像这样显式初始化数组:
bytes : aliased Byte_Array := (0 .. 9999 => 0);
但是,这对我不起作用,因为我的非易失性数据存储在地址16#0040_0000#
中,并且无法覆盖。我有什么选择?
更多信息:
我想补充一点,您可以避免通过以下方式显式初始化数组:
bytes : aliased Byte_Array := (0 .. 9999 => <>);
但是,它仍然无法编译,产生了不同的错误:
aliased object "bytes" with unconstrained array nominal subtype
can overlay only aliased object with compatible subtype
在for bytes'Address use To_Address(16#0040_0000#);
行上。
解决方法
创建自己的“访问者”对您有帮助吗?像
with Ada.Text_IO; use Ada.Text_IO;
with Interfaces;
with System;
with System.Address_Image;
procedure Byte_Arrays is
type Byte_Array is array (Natural range <>) of Interfaces.Unsigned_8;
package Access_Byte_Array is
type Byte_Array_Access is private;
function Form_Access (Of_Array : Byte_Array) return Byte_Array_Access;
function Address (Of_Array : Byte_Array_Access) return System.Address;
function Length (Of_Array : Byte_Array_Access) return Integer;
private
type Byte_Array_Access is record
The_Array : System.Address;
First : Natural;
Last : Integer; -- could have zero length
end record;
function Address (Of_Array : Byte_Array_Access) return System.Address
is (Of_Array.The_Array);
function Length (Of_Array : Byte_Array_Access) return Integer is
(if Of_Array.Last < Of_Array.First
then 0
else Of_Array.Last - Of_Array.First + 1);
end Access_Byte_Array;
package body Access_Byte_Array is
function Form_Access (Of_Array : Byte_Array) return Byte_Array_Access
is
begin
return (The_Array => Of_Array'Address,First => Of_Array'First,Last => Of_Array'Last);
end Form_Access;
end Access_Byte_Array;
use Access_Byte_Array;
Bytes : aliased Byte_Array(0 .. -9999);
for Bytes'Address use System'To_Address(16#0040_0000#);
Bytes_Access : constant Byte_Array_Access := Form_Access (Bytes);
begin
Put_Line (Length (Bytes_Access)'Image);
Put_Line (System.Address_Image (Address (Bytes_Access)));
end Byte_Arrays;
有输出
$ ./byte_arrays
10000
0000000000400000
[稍后]对于macOS上的FSF GNAT 10.1.0,这些更改有效:
type Standard_Access is access all Byte_Array;
...
function Standard_Accessor
(Of_Array : aliased Byte_Array_Access) return Standard_Access;
...
type Bounds is record
Lower : Integer;
Upper : Integer;
end record with Pack;
type Byte_Array_Access is record
The_Array : System.Address;
The_Bounds : Bounds;
end record;
...
function Standard_Accessor
(Of_Array : aliased Byte_Array_Access) return Standard_Access
is
type Raw_Accessor is record
Contents : System.Address;
Bounds_P : System.Address;
end record with Pack;
function Convert
is new Ada.Unchecked_Conversion (Raw_Accessor,Standard_Access);
Raw_Result : constant Raw_Accessor
:= (Contents => Of_Array.The_Array,Bounds_P => Of_Array.The_Bounds'Address);
begin
return Convert (Raw_Result);
end Standard_Accessor;
Standard_Accessor
的参数必须使用别名,以便通过引用而不是堆栈传递。当然,您必须注意不要在Standard_Access
存在时将其删除,因此最好始终在程序包级别进行声明。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。