使用ada中的静态库中的软件包

时间:2019-01-23 16:36:00

标签: compiler-errors ada

我想使用静态库中的包中的类型和服务。

所以,在我的身体main.adb中,放了一个

with Services.A;

Service.A位于外部库(services.a)中,因此我需要在编译过程之后链接该库。

我添加了标志-L/path/of/dir/containing/my/lib-lservices

但是由于类型声明在lib内部,并且编译器需要符号,因此我必须包括来自services.ads的规范(.ads)。

我看到了多种方法来执行此操作,但是在我的项目中没有任何效果。

我尝试添加标志-I/path/to/ads,但没有成功。

如果我在gpr文件中将规范添加到Sources_Dirs,它会告诉我单元“ Services.A”不能属于多个项目。

是否有任何官方方法可以将ada中的规范(如标头)包含在ada的外部静态库中?

1 个答案:

答案 0 :(得分:1)

这是您开始的一些事情。我希望它能为您指明方向。

当您在GPR中使用图书馆时,我知道3种情况。 请记住,这不是一个完整的答案,肯定还会有更多案例,我可能会忘记一些事情。该主题有很多陷阱,因此,由于该主题经常被提出,因此您应该深入研究Internet,AdaCore / GNAT文档和stackoverflow。根据您拥有/产生的lib的类型以及某些特定的compile / build / link选项,此处可能不包括上述一些陷阱。

序言:当您包含静态库时,其唯一的文件名不会告诉您任何有用的调用它所包含的代码的信息。因此,如果静态库为“ serivices.a”,则它只是文件名和扩展名。 with Services.A不足以调用代码。

案例1

您可以访问生成库的GPR my_lib.gpr,该库用Ada编写。 只需包含GPR,并且在您的代码中,您只能with公开接口。 (与Simon Gright关于您的GPR中的with "services.gpr";的评论相对应)

  • 如果my_lib.gpr产生一个静态lib,则无所事事! GPR会为您做必要的事情(构建/链接)。
  • 如果lib是动态(dll),则需要在执行时在OS搜索路径(可执行文件旁边或路径环境变量中)中找到dll

案例2

您可以访问生成该库的GPR my_lib.gpr,该库是用另一种语言编写的。

  • 建立图书馆
  • 定义另一个GPR my_lib_install.gpr,其中包含库接口声明(.ads文件)。如果文件不存在,请参阅情况3
  • 将GPR引用到您自己的GPR项目中
  • 您现在可以使用代码中.ads文件中定义的方法/类型。 .ads通常包含pragma Import(...)约定声明。它们只定义了一次,因此没有unit "Services.A" cannot belongs to several projects错误消息。

或者您可以将库接口声明(.ads文件)直接包含到您的项目中。

  • 如果my_lib.gpr生成静态库,则应包括适当的链接指令以使用.a文件。
  • 如果lib是动态(dll),则需要在执行时在OS搜索路径(可执行文件旁边或路径环境变量中)中找到dll

案例3

my_lib是一个COTS,它是用另一种语言编写的。 它应该随接口定义一起提供。

通常的方法是写入与提供的合同定义相对应的.ads文件。应该使用与库构建方式相对应的pragma Import(...)约定来标记类型和方法(Ada约定,C约定,请参见ARMthis wiki

通常,接口协定是.h文件(大多数库都是使用C约定生成的)。因此,您可以使用专为此目的设计的Ada的Interfaces.c软件包。 this example of interfacing Ada with Java via C convention中给出了与C接口的示例。主要区别在于您将使用pragma Import而不是pragma Export 这应该可以解决:

  

是否有任何正式方式将规范(例如标头)包含在C中   从ada的外部静态库中获取?

您可以直接将此.ads文件添加到您的源中,也可以按照开头所述编写自己的GPR进行托管。由您决定。

最后一个词,如果您的库是使用Ada语言编码的,则可以查看有关精制,“初始化”和“最终确定”符号的文档。