属性

仅自己参考使用

属性扩展

no_mangle

在Rust中,#[no_mangle]是一个属性,用于在编译时防止函数或静态变量进行名称重整(mangled)。

当Rust代码被编译时,标识符通常会被重整 — 被转换为不同的名称以包含额外的信息。例如,一个名为do_something()的函数可能会被重整为 _ZN10mycrate3foo10do_somethingEi或类似的形式。

重整可以避免在将多个crate链接在一起时出现冲突。但有时你想要禁用重整,以保留标识符的原始名称。常见情况包括:

  • 将Rust函数暴露给其他语言(如C),需要保留原始名称。
  • 定义必须与特定函数签名匹配的入口点或外部接口。

  • 通过在函数或静态定义之前添加#[no_mangle],你告诉Rust排除它们不进行重整。例如:

#[no_mangle]
pub extern fn do_something(x: i32) {
  // ...
}

这保持了do_something不进行重整,并禁用了重整。该函数可以干净地链接到外部C代码。

因此,总之,当你需要将Rust标识符以确切的名称暴露给其他语言或环境时,会使用#[no_mangle]。它有选择地禁用了Rust的默认名称重整行为。

naked

#[naked]是一个过程宏,用来表示某个汇编实现的函数主体

裸函数必须只包含一条 asm!语句:该 asm!语句的内容就是函数的主体, 没有序幕或尾声。这意味着汇编代码负责包含从函数返回的必要指令。

// The SYSV64 calling convention used on x86_64 Linux passes the first
// 2 integer arguments in EDI/ESI.
#[naked_function::naked]
pub unsafe extern "C" fn add(a: i32, b: i32) -> i32 {
    asm!(
        "lea eax, [edi + esi]",
        "ret",
    );
}

#[test]
fn main() {
    let ret = unsafe { add(1, 2) };
    assert_eq!(ret, 3);
}

ABI 和其他注意事项:

Naked functions must be marked as unsafe.

The function must have one of the following whitelisted ABIs:

  • "C"
  • "C-unwind"

Only the following attributes are supported on naked functions:

#[export_name]
#[no_mangle]
#[link_section]
#[cfg]
#[doc] or /// doc comments