Rust 库
Rust 库的集成将基于 BLAKE3 哈希函数的集成进行描述。
集成的第一步是将库添加到 /rust 文件夹中。为此,您需要创建一个空的 Rust 项目并在 Cargo.toml 中包含所需的库。此外,还需要通过在 Cargo.toml 中添加 crate-type = ["staticlib"]
来配置新的库编译为静态库。
接下来,您需要使用 Corrosion 库将库链接到 CMake。第一步是在 /rust 文件夹内的 CMakeLists.txt 中添加库文件夹。之后,您应该在库目录中添加 CMakeLists.txt 文件。在其中,您需要调用 Corrosion 导入函数。这些行用于导入 BLAKE3:
因此,我们将使用 Corrosion 创建一个正确的 CMake 目标,然后使用一个更便利的名称重命名它。请注意,名称 _ch_rust_blake3
来自 Cargo.toml,其中它被用作项目名称(name = "_ch_rust_blake3"
)。
由于 Rust 数据类型与 C/C++ 数据类型不兼容,我们将使用我们的空库项目为从 C/C++ 接收的数据创建适配方法,调用库方法,并为输出数据进行反向转换。例如,针对 BLAKE3 编写了这个方法:
该方法以 C 兼容的字符串、其大小和输出字符串指针作为输入。然后,它将 C 兼容的输入转换为实际库方法所使用的类型并调用它们。在此之后,它应该将库方法的输出转换回 C 兼容类型。在这种特定情况下,库支持通过 fill() 方法直接写入指针,因此不需要转换。这里的主要建议是创建尽量少的方法,这样您在每次调用方法时需要进行的转换就会更少,不会产生过多的开销。
值得注意的是,#[no_mangle]
属性和 extern "C"
对所有此类方法都是强制性的。没有它们,将无法执行正确的 C/C++ 兼容编译。此外,它们是集成的下一步所必需的。
在编写完适配方法的代码后,我们需要为库准备头文件。这可以手动完成,或者您可以使用 cbindgen 库自动生成。在使用 cbindgen 的情况下,您需要编写一个 build.rs 构建脚本,并将 cbindgen 作为构建依赖项包含。
一个可以自动生成头文件的构建脚本示例:
此外,您应该对每个 C 兼容的属性使用属性 #[no_mangle] 和 extern "C"
。没有它,库可能会错误编译,cbindgen 将无法启动头文件的自动生成。
完成所有这些步骤后,您可以在一个小项目中测试您的库,以查找与兼容性或头文件生成相关的所有问题。如果在头文件生成过程中出现任何问题,您可以尝试使用 cbindgen.toml 文件进行配置(您可以在这里找到模板:https://github.com/eqrion/cbindgen/blob/master/template.toml)。
值得注意的是在集成 BLAKE3 时遇到的问题: MemorySanitizer 可能会引发误报,因为它无法判断某些 Rust 中的变量是否已初始化。通过为某些变量编写更明确定义的方法解决了这个问题,尽管此方法的实现较慢,仅用于修复 MemorySanitizer 构建。