使用GNAT Ada和Gnu C++,我将Ada代码与c ++包装器连接起来,我想在运行这个(愚蠢的)代码时正确捕获Ada异常:
with ada.text_io;
package body ada_throw is
procedure ada_throw is
begin
ada.text_io.put_line ("hello");
raise program_error;
end ada_throw;
end ada_throw;
Run Code Online (Sandbox Code Playgroud)
相关规范代码是:
package ada_throw is
procedure ada_throw;
pragma export (convention => C, entity => ada_throw, external_name => "ada_throw");
end ada_throw;
Run Code Online (Sandbox Code Playgroud)
在C++方面这样做:
#include <iostream>
extern "C"
{
void ada_throw();
void adainit();
}
int main()
{
adainit();
ada_throw();
std::cout << "end of program" << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我明白了:
hello
raised PROGRAM_ERROR : ada_throw.adb:8 explicit raise
Run Code Online (Sandbox Code Playgroud)
所以异常机制的工作,我没有得到我的C++程序的最后打印和返回代码为非零.
现在我想抓住异常.如果我使用catch(...) …
我正在大学开设编程课程,选择的语言是Ada.我在Kate编写代码并使用GNAT 4.6.3进行编译.我们必须为我们的程序使用教师提供的库,如下所示:
with foo;
use foo;
Run Code Online (Sandbox Code Playgroud)
当然,然后该文件foo.adb
必须包含在与我的源文件相同的目录中.由于多个项目依赖于这个库,并且我喜欢将每个项目保存在自己的子目录中,因此我必须将库文件复制到每个新项目中.更不用说我的库代码和源代码都在同一目录中.
那么有什么方法可以去:
with ../../lib/foo
use ../../lib/foo
Run Code Online (Sandbox Code Playgroud)
?
我已经尝试了一下,但我发现的只是关于编译器选项的东西.我宁愿不必乱用那些,特别是因为只有某些项目需要这个特定的库,所以将它添加到全局编译器设置并让编译器毫无意义地搜索路径它没有意义不需要搜索.
我正在编程中学习Ada 95,我想在我的MacBook上安装gnat编译器.我不知道在哪里可以获得一个好的gnat来编译我的代码,以及如何安装它.
我目前有gedit作为我的文本编辑器,因为这是我们在实验室环境中使用的.我是Mac世界的新手,所以任何帮助都会非常感激.
我正在尝试创建一个ada库,并尝试了一些不同的东西.我尝试使用makefile编译项目并尝试从所有.o文件创建一个库这似乎不能按预期工作.然后我问adacore支持,他们指出了我在ada和c项目中使用.gpr文件的方向,以及应该创建库的ada.gpr中的文件.这几乎可以工作,但当它试图编译ada我得到未定义的引用.
我试过的:命令行:
ar rc libmy_lib.a *.o
Run Code Online (Sandbox Code Playgroud)
当我尝试阅读lib中的内容时
ld libmy_lib.a
Run Code Online (Sandbox Code Playgroud)
我得到这个错误ld:警告:找不到条目符号_start; 没有设置起始地址
项目文件:我的ada项目文件prj.gpr
project Prj is
for Source_Dirs use ("source1/", "source2", ....);
for Object_Dir use ".";
for Languages use ("Ada");
for Library_Name use "test";
for Library_Dir use "lib";
for Library_Interface use (
--All my ada packages
);
package Naming is
for Spec_Suffix ("ada") use ".1.ada";
for Body_Suffix ("ada") use ".2.ada";
for Separate_Suffix use ".2.ada";
for Dot_Replacement use ".";
end Naming;
package Compiler is
for Default_Switches ("ada") use ("-v", "-g", "-gnato", "-gnatwa", …
Run Code Online (Sandbox Code Playgroud) 使用GPRBuild,我创建了一个名为的库项目Lib
.所有包都Lib
驻留在包中Base
,我将其用作基本包:具有基本包Base
.例如,如果我要Apple
在我创建的任何库或应用程序中创建包,它将被写为package Base.Apple
.
这个问题,使用GPRBuild.为了把东西放在Base
包装下面,它需要存在.Lib
因此,在GPRBuild库项目中,我有一个base.ads
表示包存在的文件Base
.然后在我正在使用该库的项目中Lib
,让我们将其称为Proj
,我也将所有包放在Base
包(包内Proj
)中.为了做到这一点,我们需要使用包定义来创建一个base.ads
文件.Proj
Base
我们来看看gpr
项目文件:
with "lib.gpr";
project Proj is
-- ...
end Proj;
Run Code Online (Sandbox Code Playgroud)
通过这个出现了问题; 我们突然有两个文件,都叫做base.ads
,都定义了Base
包,每个项目一个:库项目Lib
,以及Proj
使用库的项目Lib
.由于我们有两个包(和它们的文件)命名相同的东西,我们得到这个错误,这在编译时完全不奇怪:
unit "base" cannot belong to several projects
问题是:有没有办法在多个项目中拥有相同的基础包?然后通过import(with
)链接在一起的项目.如果它应该被证明是可能的,它怎么能实现呢?
我遇到了一个问题,在 Ada 中使用不能被系统Storage_Unit
(如运行时定义的system.ads
)整除的模块化类型将Constraint_Error
在运行时在访问时引发 a 。我最初在使用最小运行时间的裸机系统上遇到这个问题,同时尝试通过将 12 位数组覆盖在内存中的缓冲区上来从缓冲区读取 12 位值。有谁知道为什么会这样?
以下最小示例说明了我遇到的问题。我使用 AdaCore 的 GNAT 2019 对此进行了测试,并使用包含的zfp
运行时编译。使用标准运行时不会重现该问题。
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
----------------------------------------------------------------------------
-- Modular type with standard size divisible by 8.
----------------------------------------------------------------------------
type Type_One is mod 2 ** 16;
type Buffer_Type_One is array (1 .. 128) of Type_One;
----------------------------------------------------------------------------
-- Modular type with non-base 8 size.
----------------------------------------------------------------------------
type Type_Two is mod 2 ** 12;
type Buffer_Type_Two is array (1 .. 128) …
Run Code Online (Sandbox Code Playgroud) 我一直在浏览本Ada 95教程。我读到的是,可以定义一个范围与标准范围不同的类型,如果程序试图超出该范围,则将引发错误。在我自己的程序上工作时,我注意到,如果定义中范围的末尾落在其基础类型的边界上,那么当分配超出该范围的值时,程序将不会提高CONSTRAINT_ERROR。取而代之的是它将快乐地继续前进,然后环绕。我编写了一个程序来明确显示这一点。
有人知道解释这种行为的Ada规则吗?
-柯克
这是我终端的输出,源代码在下面。
me@acheron:~/Dropbox/programs/ada$ gnatmake constraints.adb -f
gcc-4.6 -c constraints.adb
gnatbind -x constraints.ali
gnatlink constraints.ali
me@acheron:~/Dropbox/programs/ada$ ./constraints
Type ON has size: 7
It has a min/max of: 0 127
It's base has a min/max of: -128 127
Type UNDER has size: 7
It has a min/max of: 0 126
It's base has a min/max of: -128 127
The value of No_Error is: 245
raised CONSTRAINT_ERROR : constraints.adb:58 range check failed
me@acheron:~/Dropbox/programs/ada$
Run Code Online (Sandbox Code Playgroud)
源代码:
with Ada.Text_IO, Ada.Integer_Text_IO;
use …
Run Code Online (Sandbox Code Playgroud) 我想编写一个非常简单的驱动程序来初始化,写入/读取微控制器上的某些外设,就像我在C中完成的那样.我以GPIO外设为例进行初始化,写入和读取.
GPIOA : GPIO_Register with
Volatile,
Address => System'To_Address (GPIOA_Base);
pragma Import (Ada, GPIOA);
Run Code Online (Sandbox Code Playgroud)
如果我声明一个列表来访问所有GPIO:
type GPIO_Register_ptr is access all GPIO_Register with volatile;
Gpio_List_Pointers : array (Integer range 1 .. 8) of aliased GPIO_Register_ptr;
Run Code Online (Sandbox Code Playgroud)
然后分配:
Gpio_List_Pointers(1) := GPIOA'Access;
Run Code Online (Sandbox Code Playgroud)
我收到错误:
142:29 prefix of "ACCESS" attribute must be aliased
Run Code Online (Sandbox Code Playgroud)
任何想法如何解决?
是否可以通过GNAT中的环境变量将多个对象传递给链接器?我遇到的情况是,我有一个环境变量(我们称其为LINKLIBS),其中包含以空格分隔的额外库列表,这些库在链接时将被带入可执行文件。在GNU Make中,我们仅将链接行定义为“ $(LD)-o output_file main.o obj1.o obj2.o $(LINKLIBS)”,链接器会将LINKLIBS中的所有内容带入对象,但前提是通常的规则。
LINKLIBS可能看起来像这样:“ /usr/lib/libsource-highlight.a /usr/lib/x86_64-linux-gnu/libGLU.a /usr/lib/x86_64-linux-gnu/libmenu.a”
当我在GPR Linker程序包中明确指定了以下两个对象时,它可以正常工作:
package Linker is
for Default_Switches ("Ada")
use (
"--for-linker=-Map",
"--for-linker=../myprog.map",
"--for-linker=--start-group",
external("LIB_PATH") & "/libabc.a",
external("LIB_PATH") & "/lib123.a",
"--for-linker=--end-group");
end Linker;
Run Code Online (Sandbox Code Playgroud)
但是,如果我包含一个以空格分隔的存档文件列表的环境变量,则会收到错误消息:
package Linker is
for Default_Switches ("Ada")
use (
"--for-linker=-Map",
"--for-linker=../myprog.map",
"--for-linker=--start-group",
external("LIB_PATH") & "/libabc.a",
external("LIB_PATH") & "/lib123.a",
external("LINKLIBS"),
"--for-linker=--end-group");
end Linker;
Run Code Online (Sandbox Code Playgroud)
gcc: error: /usr/lib/libsource-highlight.a /usr/lib/x86_64-linux-gnu/libGLU.a /usr/lib/x86_64-linux-gnu/libmenu.a: No such file or directory
Run Code Online (Sandbox Code Playgroud)
因此,似乎将Linker程序包中的单个参数解释为包含空格的单个文件。我认为这些项目需要用逗号分隔或以某种方式分隔,但是我该如何以对我的GCC创建的程序和GNAT创建的程序使用相同的变量的方式来执行此操作?