Skip to content
On this page

这篇文章主要是介绍一个小技巧,怎么将全局变量当做函数指针来使用. 注意这里不可避免的使用到unsafe.

先说一下,要解决的问题,console.rs 是在这样一个crate,这个crate既要在内核中使用,也要在普通用户程序中使用. 但是我又想要一个打印日志的功能,怎么做呢?.

1. 声明全局变量

rust
pub static mut fn_console_putchar:usize=0; // 全局变量,用于记录控制台的地址

2. 初始化

rust
pub fn set_console_putchar(f: *const ()){
    unsafe {
        fn_console_putchar=f as usize;
    }
}

3. 使用

rust
pub fn console_putchar(c: usize){
    unsafe{
        if fn_console_putchar==0 {
            panic!("fn_console_putchar not set  ");
        }
        let p= fn_console_putchar as *const ();
        let f: fn(usize)= core::mem::transmute(p);
        f(c);
    }
}
impl Write for Stdout {
    fn write_str(&mut self, s: &str) -> fmt::Result {
        for c in s.chars() {
            console_putchar(c as usize);
        }
        Ok(())
    }
}

pub fn print(args: fmt::Arguments) {
    Stdout.write_fmt(args).unwrap();
}

4. 外部crate如何使用

rust
fn putchar(c:usize){
    println!("{}",c as u8 as char);
}
fn main() {
    set_console_putchar(putchar as *const());
    ...
}

这体现出了unsafe的强大性,也体现出了rust作为系统语言,应付各种需求的能力.