我正在使用AdaCore GPS(GPL)IDE使用GNAT编译器学习Ada,目标是ARM"裸板"硬件(使用Ravenscar SFP运行时的STM32F4)。
对于我的基于ARM的嵌入式工作,我来自C / C ++背景。
无论如何,我已经实现了最后一次机会处理程序"这定义如下,
procedure Last_Chance_Handler (Msg : System.Address; Line : Integer);
pragma Export (C, Last_Chance_Handler, "__gnat_last_chance_handler");
以下是实际程序(来自.adb
文件的摘录),
procedure Last_Chance_Handler (Msg : System.Address; Line : Integer) is
begin
LEDs_All_On;
-- Put_Line("Detail :" & Address_To_String(Msg));
Put_Line("Line :" & Line'Image);
loop
null;
end loop;
end Last_Chance_Handler;
Msg
参数记录如下,
Msg参数是一个以C结尾的字符串,表示 raise语句的源位置,由编译器生成, 或者,如果编译指示Suppress_Exception_Locations为,则为零长度字符串 使用
我一直试图弄清楚如何将null
已终止的Msg
字节转换为Ada字符串,以便我可以使用Put_Line()
调用显示它(在调试时)我可以通过半主机机制访问这种类型的输出。
我之前通过将其'Address
属性设置为常量值,将Ada记录(代表设备寄存器等)映射到物理内存地址。但是,这是我第一次通过变量中保存的System.Address
值尝试访问内存。
有人可以建议我如何实施Address_To_String()
程序吗?
我已经尝试过Ada字节数组和它们与System.Address
之间未经检查的转换,还有Ada指针,但到目前为止我还没有取得任何成功。
非常感谢任何帮助或建议!
非常感谢,
...最大
答案 0 :(得分:3)
您正在寻找的操作可能是Interfaces.C.Strings.Value
。它需要Interfaces.C.Strings.chars_ptr
类型的参数(相当于C中的char *
)并返回String
。
答案 1 :(得分:3)
如果Jacob’s answer不清楚,你可以完全自由地宣布
with Interfaces.C.Strings;
procedure Last_Chance_Handler
(Msg : Interfaces.C.Strings.chars_ptr; Line : Integer);
请记住Msg
。
答案 2 :(得分:3)
如果你来到last_chance_handler,可能会出现问题,你不应该太依赖你的环境。 Ada.Text_IO是一个非常重的包。你应该尽量避免它,特别是在这里。
您可以尝试这样的事情:
with GNAT.IO;
with System.Storage_Elements;
procedure Last_Chance_Handler
(Msg : System.Address; Line : Integer)
is
use System.Storage_Elements; -- make "+" visible for System.Address
function Peek (Addr : System.Address) return Character
is
C : Character with Address => Addr;
begin
return C;
end Peek;
A : System.Address := Msg;
begin
GNAT.IO.Put ("line :");
GNAT.IO.Put (line); -- avoid the secondary stack for Line'Image
GNAT.IO.New_Line;
while Peek(A) /= ASCII.NUL loop
GNAT.IO.Put (Peek(A));
A := A + 1;
end loop;
GNAT.IO.New_Line;
end;