属性
仅自己参考使用
属性扩展
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