1个不稳定版本
使用旧的Rust 2015
0.1.0 | 2015年4月13日 |
---|
#10 在 #porting
27KB
345 行
probe-c-api
probe-c-api
的目的是处理以下情况:一个C库的API足够了解,可以编写使用该库的C代码,但对其接口的了解不足以编写另一种语言(如Rust)的绑定。
在这种情况下,有三种可能的方法
-
获取库并手动为该特定库编写绑定。如果预先知道库的ABI非常稳定,这种方法效果最好,无论这是否是设计使然,或者是因为绑定集的用户很可能在实际中只使用一个特定的版本。
如果绑定必须有许多变体,例如为了适应不同的平台、C编译器、配置选项和/或库版本,这种方法通常都会失败。
-
解析C头文件并提取所需信息。例如,
bindgen
就采用这种方法。对于将要运行使用目标C库的软件的特定机器,这种方法非常有效。这种方法的一个潜在问题是它很难实现。为了既通用又健壮,这样的系统必须包含完整的C编译器的许多功能,包括预处理器、解析器和类型检查器的一些部分。也许更严重的是,这样的系统必须复制C编译器的非可移植属性,例如特定平台的整数大小或非标准属性和其他语法扩展。
最后,对头文件的简单分析可能包括宏、类型或对象,这些在生成的绑定中实际上并不存在于文档化的API中,导致不稳定的元素和类似私有实现细节在输出中被暴露。
-
使用库编译、然后可选地链接和运行用C编写的简短测试函数。通过监控每个步骤的退出状态和输出,可以探测C库的细节。这是
probe-c-api
的方法,也是许多现有构建系统工具包的方法,例如autotools和CMake。这种方法的优势在于,它通过C编译器检查针对目标库编译的程序的实际行为,但这种检查是由对API的文档知识的指导进行的,这些知识由绑定开发者输入。这导致了一种“两者之最佳”的情况,其中创建正确绑定的能力不依赖于关于库、平台或C编译器的硬编码知识。
也许这种方法的最大的缺点是它不适合交叉编译。为了探测C库,通常需要在本地运行与之链接的程序。
这种方法的另一个缺点是探测必须依赖于许多“移动部件”。具体来说,它必须有一个可用的C编译器,能够使用正确的标志调用该编译器以构建可运行的程序,能够在兼容的环境中运行该程序(例如,动态链接到正确的库),并从操作系统获取子进程的输出和返回状态。
虽然这看起来可能不是那么高的门槛,但在非标准或新型平台上,或与罕见的C编译器一起进行此类测试时,测试失败的情况并不少见。因此,
probe-c-api
并不直接调用C编译器,而是要求用户提供一个将C源文件转换为目标文件的方法。同样,它也不直接调用产生的程序,而是要求用户提供一个可以调用程序并返回输出结果的方法。这有望产生比autotools等系统更灵活、更模块化的系统(大多数人使用它们的方式)。一个封装C编译器的库可以处理编译,
probe-c-api
可以处理自动生成测试程序并解释结果,标准库可以处理与操作系统的交互,用户可以处理与他们特定情况相关的任何怪癖。特别是,用户可以通过在构建平台外运行测试程序,通过网络发送可执行文件,将其发送到作为外围设备的机器,或发送到模拟器来处理交叉编译。不是巧合的是,通过要求用户指定探测如何与C编译器和目标平台交互,这种设计缩小了
probe-c-api
的范围,使其作为一个独立的crate实现起来更加简单。
依赖关系
~315–540KB