#struct #layout #explicit

struct_layout

使用这个奇怪的技巧来自定义结构体布局

1 个不稳定版本

0.1.0 2019年4月20日

#594 in 过程宏

MIT 许可证

35KB
668

结构体布局

MIT License crates.io docs.rs

使用显式控制字段来自定义结构体布局。

用法

此进程宏可在crates.io上找到。

文档可以在docs.rs上找到。

在您的Cargo.toml中,添加以下内容

[dependencies]
struct_layout = "0.1"

示例

#[struct_layout::explicit]属性应用于结构体定义,并在每个字段声明上放置#[field]属性。

语法从C# [StructLayout]属性中汲取灵感。

/// Doc comments are allowed.
#[struct_layout::explicit(size = 32, align = 4)]
#[derive(Copy, Clone, Debug, Default)]
pub struct Foo {
	#[field(offset = 21, get, set)]
	pub unaligned: f32,

	/// Documenting the fields works too.
	#[field(offset = 4)]
	pub int: i32,
}

这里有很多东西要解释,让我们一步一步来。

struct_layout::explicit属性

此属性必须应用于结构体定义,属性参数顺序固定

结构体的大小和对齐方式是必需的,格式为size = <usize>align = <usize>

以下是一个可选的check(..)参数,它指定了一个必须由所有字段成员实现的特质约束。这允许自定义特质确保所有字段类型都是安全的。如果不存在,则所有字段都必须实现Copy

其他属性

由于转换具有侵略性,因此仅支持一小部分白名单属性

  • 允许使用doc注释,并将其应用于最终生成的结构。
  • 使用白名单标识符的derive

生成的结构

这个进程宏生成一个新类型元组结构,它包装了一个长度由size参数指定的字节数组。该结构通过Calign表示形式,使用由align参数指定的对齐方式来装饰。指定的可见性应用于生成的结构。还添加了任何文档注释。

基本上,这是

/// Doc comments are allowed.
#[repr(C, align(4))]
pub struct Foo([u8; 32]);

支持的自动派生特性

唯一支持自动派生的特性是CopyCloneDebugDefault。未来的扩展可能允许支持更多特性。

别忘了你可以在生成的类型上实现额外的方法和特性!

结构字段语法

结构中的每个字段都必须伴随一个单一的#[field(..)]属性。不允许使用除doc注释以外的任何属性。

字段属性必须以指定字段的偏移量开始,使用offset = <usize>。接着是一个列表,说明如何实现字段的访问。

支持的方法有getsetrefmut。如果没有指定任何方法,将实现该字段的全部方法。访问器方法具有where子句,要求字段类型实现由struct_layout::explicit属性的check参数指定的特性。

访问器通过以下签名的方法实现

  • get: fn field(&self) -> T
  • set: fn set_field(&mut self, value: T) -> &mut Self
  • ref: fn field_ref(&self) -> &T
  • mut: fn field_mut(&mut self) -> &mut T

获取和设置允许未对齐偏移量。如果任何字段具有ref或mut访问器,则字段偏移量和指定的结构体对齐方式必须是字段类型对齐方式的倍数。

如果字段偏移量超出范围或未对齐(如果需要),将生成一个无法理解的错误,抱怨const评估失败。由于这些约束是通过静态断言的(使用数组大小技巧),这是不幸的。

安全性

所有字段都必须实现Copy或由check参数指定的特质界限。这种限制使得事情更安全,但绝对不是完美的。通过使用这个库,你承诺不会做愚蠢的事情,并可能将问题提交到错误跟踪器中,以便提高安全性。

在任何情况下,都不应允许字段实现Drop或成为引用类型。这是不受支持的。

如何构建实例

如果请求,则可能自动推导出Default特质,并用它们的类型默认值填充字段。您可以为生成的结构体添加额外的关联方法。

还可能使用不安全的std::mem::zeroed来创建一个零初始化的实例,如果这有意义的话。

与no_std兼容性

生成的代码与no_std兼容!

许可证

MIT许可证下许可,请参阅license.txt

贡献

除非你明确表示,否则,你故意提交的任何旨在包含在你所做工作的贡献,都将按上述方式许可,没有任何额外的条款或条件。

无运行时依赖