Appearance
这篇文章主要是介绍一个小技巧,怎么将全局变量当做函数指针来使用. 注意这里不可避免的使用到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作为系统语言,应付各种需求的能力.