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 的外部静态库中包含 C 中的标头等规范?
解决方案
这里有一些东西让你开始。我希望它能给你一个好的方向。
当您将库用于 GPR 时,我知道 3 种情况。请记住,这不是一个完整的答案,肯定存在更多案例,我可能会忘记一些事情。该主题存在陷阱,因此您应该深入研究互联网、AdaCore/GNAT 文档和 stackoverflow,因为该主题经常被提出。根据您拥有/生成的库的类型以及一些特定的编译/构建/链接选项,此处可能不会涵盖某些上述陷阱。
前言:当你包含一个静态库时,它的唯一文件名不会告诉你任何有用的信息来调用它包含的代码。所以如果静态库是“serivices.a”,它只是一个文件名和扩展名。with Services.A
不足以调用代码。
情况1
您可以访问my_lib.gpr
生成库的 GPR,它是用 Ada 编写的。只需包含 GPR,在您的代码中您将只被允许访问with
公开的接口。(它对应于 Simon Wright 关于with "services.gpr";
GPR 中的评论)
- 如果
my_lib.gpr
产生了一个静态库,那就没什么可做的了!GPR 为您做必要的事情(构建/链接)。 - 如果 lib 是动态的 (dll),则需要在执行时在 OS 搜索路径中找到该 dll(在可执行文件旁边,或在路径环境变量中)
案例2
您可以访问my_lib.gpr
生成库的 GPR,它是用另一种语言编写的。
- 建立图书馆
my_lib_install.gpr
定义另一个包含库接口声明(.ads
文件)的GPR 。如果文件不存在,请参阅案例 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 约定,参见ARM或此 wiki)
通常,接口契约是一个.h
文件(大多数库都是使用 C 约定生成的)。因此,您可以使用 AdaInterfaces.c
专为此设计的软件包。在通过 C 约定将 Ada 与 Java 连接的示例中给出了与 C 连接的示例)。主要区别在于您将不得不pragma Import
而不是pragma Export
This should anwser to:
是否有任何官方方法可以从 ada 的外部静态库中包含 C 中的标头等规范?
您可以直接将此.ads
文件包含到您的源中,也可以编写自己的 GPR 来进行如开头所述的托管。它是由你决定。
最后一句话,如果你的库是用 Ada 语言编码的,你可以看看关于elaboration、 'initialize' 和 'finalize' 符号的文档。
推荐阅读
- python - 指定用于多重继承的父类
- javascript - CR和CF的javascript textarea maxlength问题
- vb.net - 为什么我的 if 语句只返回第二个结果?
- javascript - Android Webview:本地 html 加载外部 css 和 .js 文件 - 无法访问外部 .js 中的功能
- ios - 如何使用 Firebase 设置密码续订电子邮件?
- java - TSP 健身水平已关闭
- java - 替换部分xml,导航组件
- flutter - 如何永久删除 Dart DevTools?
- python - 使用 `snakemake` 的 MD 任务
- sorting - select2 以所需的顺序以编程方式选择选项