47 个版本
0.3.28 | 2024 年 8 月 11 日 |
---|---|
0.3.27 | 2024 年 6 月 5 日 |
0.3.26 | 2024 年 5 月 6 日 |
0.3.25 | 2024 年 3 月 7 日 |
0.1.1 | 2019 年 1 月 27 日 |
#8 in 过程宏
205,439 次每月下载
用于 281 个crate(64 直接使用)
25KB
227 行
Linkme:安全跨平台链接器技巧
组件 | Linux | macOS | Windows | FreeBSD | OpenBSD | illumos | 其他...† |
---|---|---|---|---|---|---|---|
分布式切片 | 💚 | 💚 | 💚 | 💚 | 💚 | 💚 |
† 我们欢迎PR添加对未在此列出的任何平台的支持。
[dependencies]
linkme = "0.3"
支持 rustc 1.62+
分布式切片
分布式切片是由链接器将静态元素收集到二进制文件的连续部分中的集合。切片元素可以从最终二进制文件的依赖图中的任何位置单独定义。
实现基于 link_section
属性和平台特定的链接器支持。它不涉及任何平台的生命周期之前或任何其他运行时初始化。这是一个零成本的抽象,完全在编译和链接期间运行。
声明
静态分布式切片通过在类型为 [T]
的静态项上编写 #[distributed_slice]
来声明,其中 T
是某种类型。
use linkme::distributed_slice;
#[distributed_slice]
pub static BENCHMARKS: [fn(&mut Bencher)];
元素
切片元素可以通过在 #[distributed_slice(...)]
属性中注册到分布式切片中,其中分布式切片的路径以括号给出。初始化器必须是一个常量表达式。
use linkme::distributed_slice;
use other_crate::BENCHMARKS;
#[distributed_slice(BENCHMARKS)]
static BENCH_DESERIALIZE: fn(&mut Bencher) = bench_deserialize;
fn bench_deserialize(b: &mut Bencher) {
/* ... */
}
元素可以定义在声明分布式切片的同一包中,或者在任何下游包中。在最终二进制文件中链接的所有包中的元素在运行时都将观察到存在于切片中。
分布式切片的行为与 &'static [T]
完全相同。
fn main() {
// Iterate the elements.
for bench in BENCHMARKS {
/* ... */
}
// Index into the elements.
let first = BENCHMARKS[0];
// Slice the elements.
let except_first = &BENCHMARKS[1..];
// Invoke methods on the underlying slice.
let len = BENCHMARKS.len();
}
编译器将要求静态元素类型与分布式切片的元素类型匹配。如果两者不匹配,则程序无法编译
#[distributed_slice(BENCHMARKS)]
static BENCH_WTF: usize = 999;
error[E0308]: mismatched types
--> src/distributed_slice.rs:65:19
|
17 | static BENCH_WTF: usize = 999;
| ^^^^^ expected fn pointer, found `usize`
|
= note: expected fn pointer `fn(&mut other_crate::Bencher)`
found type `usize`
函数元素
作为分布式切片包含函数指针的常见情况的缩写,分布式_slice 属性可以直接应用于函数定义,将对该函数的指针放入分布式切片中。
use linkme::distributed_slice;
#[distributed_slice]
pub static BENCHMARKS: [fn(&mut Bencher)];
// Equivalent to:
//
// #[distributed_slice(BENCHMARKS)]
// static _: fn(&mut Bencher) = bench_deserialize;
//
#[distributed_slice(BENCHMARKS)]
fn bench_deserialize(b: &mut Bencher) {
/* ... */
}
许可协议
根据您的选择,受Apache License, Version 2.0 或 MIT license 许可。除非您明确声明,否则您提交的任何有意包含在此包中的贡献,如Apache-2.0许可证中定义的,应按上述方式双许可,不附加任何额外条款或条件。
依赖关系
~270–720KB
~17K SLoC