You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

嵌入式C转Rust:静态变量地址关联全局变量初始化问题求助

Rust中实现C风格全局变量地址+偏移的静态初始化

问题场景

在C语言中,可直接通过全局变量地址加偏移量初始化另一个全局变量,地址解析延迟到链接阶段完成,示例代码如下:

#define MASK 0xffff0000

int arr[128] = {0};
uint64_t arr_table[2] = {arr + MASK, 0};

这类变量需编译期可见,供外部内核汇编等代码访问。但迁移到Rust时,直接尝试指针转整数加偏移会触发编译错误:

尝试的Rust代码:

pub static arr: [u32; 128] = [0; 128];
pub static arr_table: [u64; 2] = [&arr as *const [u32; 128] as u64 + 0xffff0000, 0];

编译器报错:

error: pointers cannot be cast to integers during const eval

note: at compile-time, pointers do not have an integer value
note: avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior

使用mem::transmute也会得到类似错误,核心原因是Rust编译期无法获取静态变量的绝对地址,而C是将地址计算延迟到了链接阶段。

解决方案

Rust的const_eval限制了编译期指针转整数的操作,但可通过链接器脚本或Rust链接属性+链接器表达式实现等效效果,将地址计算交给链接器处理。

方法1:链接器脚本定义符号

  1. 编写链接器脚本(如linker.ld),定义计算后的符号:
MASK = 0xffff0000;
arr_table_entry = ADDR(arr) + MASK;
  1. 在Rust代码中引用该链接器符号:
#[link_section = ".data"]
pub static arr: [u32; 128] = [0; 128];

// 声明链接器定义的外部符号
extern "C" {
    static arr_table_entry: u64;
}

// 构建目标数组,填入链接器计算的值
#[link_section = ".data"]
pub static arr_table: [u64; 2] = [unsafe { arr_table_entry }, 0];
  1. 编译时指定链接器脚本:
rustc --link-arg=-Tlinker.ld your_code.rs

若使用Cargo,需在.cargo/config.toml中添加:

[build]
rustflags = ["-C", "link-arg=-Tlinker.ld"]

方法2:利用GNU链接器表达式(无需单独脚本)

依赖GNU链接器特性,直接在Rust代码中通过链接器表达式计算地址:

#[used]
#[link_section = ".data"]
pub static arr: [u32; 128] = [0; 128];

#[link_section = ".data"]
#[used]
pub static arr_table: [u64; 2] = [
    // 告诉链接器填入ADDR(arr) + 0xffff0000的计算结果
    #[link_name = "ADDR(arr) + 0xffff0000"]
    unsafe { core::mem::transmute::<u64, u64>(0) },
    0,
];

注意事项

  • 标记#[used]或指定链接段,防止编译器优化掉未直接引用的静态变量;
  • 涉及链接器符号的操作需包裹在unsafe块中,Rust无法保证符号有效性;
  • 两种方法均与C实现逻辑一致:编译期保留符号引用,链接阶段完成地址计算与填充。

内容的提问来源于stack exchange,提问作者w568w

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 15:00:55