使用ada中静态库中的包

问题描述 投票:0回答:1

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

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

with Services.A;

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

我添加了旗帜-L/path/of/dir/containing/my/lib-lservices

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

我看到了多种方法可以做到这一点,但不是我的项目。

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

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

是否有任何官方方法可以在ada中包含来自外部静态库的C中的标题等规范?

compiler-errors ada
1个回答
1
投票

这里有一些你可以开始的东西。我希望它可以让你朝着一个好方向前进。

当您将库用于GPR时,我知道有3个案例。请记住,这不是一个完整的答案,肯定存在更多的案例,我可能会忘记一些事情。该主题存在缺陷,因此您应该深入研究interwebs,AdaCore / GNAT文档和stackoverflow,因为这个主题经常被提出。根据您拥有/生成的库的类型以及一些特定的编译/构建/链接选项,这里可能不会涉及一些所述缺陷。

前言:当您包含静态库时,其唯一的文件名不会告诉您调用它包含的代码有什么用处。因此,如果静态库是'serivices.a',它只是一个文件名和扩展名。 with Services.A不足以调用代码。

情况1

您可以访问生成库的GPR my_lib.gpr,它是用Ada编写的。只需包含GPR,在您的代码中,您只能被允许使用with暴露的接口。 (它对应于Simon Wright关于GPR中with "services.gpr";的评论)

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

案例2

您可以访问生成库的GPR my_lib.gpr,并使用其他语言编写。

  • 建立图书馆
  • 定义另一个包含库接口声明(my_lib_install.gpr文件)的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这个应该回事:

是否有任何官方方法可以在ada中包含来自外部静态库的C中的标题等规范?

您可以直接将此.ads文件包含在您的源中,或者编写您自己的GPR以执行该托管,如开头所示。它是由你决定。

最后一句话,如果您的库是用Ada语言编写的,您可以查看有关详细说明,“初始化”和“最终确定”符号的文档。

© www.soinside.com 2019 - 2024. All rights reserved.