zoukankan      html  css  js  c++  java
  • Rust Lang Book Ch.19 Unsafe

    Unsafe

    Unsafe能够绕开rust强调的内存安全保证(memory safety guarantees),Unsafe的五大功能是:

    1. Dereference a raw pointer,获取一个裸指针对应的数据

    2. 调用其他unsafe的代码

    3. 获取或者修改可变的static变量

    4. 实现unsafe的特性

    5. 获取union的域

    unsafe不能关闭borrow checker,只有这5个功能。

    书中建议将unsafe代码用安全的API包裹起来。

    Unsafe-Dereference a raw pointer

    Rust中raw pointer有*const T和*mut T两种。

        let mut num = 5;
    
        let r1 = &num as *const i32;
        let r2 = &mut num as *mut i32;

    unsafe { println!("r1 is: {}", *r1); println!("r2 is: {}", *r2); }

      

    raw pointer与引用和smart pointer的不同之处在于:

    1. 允许忽略borrowing rule,可以有多个同时写

    2. 不保证指向有效的memory

    3. 可能是null

    4. 没有自动的内存释放和清理

        let address = 0x012345usize;
        let r = address as *const i32;
    

      

    这里使用as将引用映射为对应的raw pointer。

    程序员可以在safe code中创建raw pointer,但是只被允许在unsafe code中dereference这些指针。

     Unsafe-Calling an unsafe Function or Method

    use std::slice;
    
    fn split_at_mut(slice: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) {
        let len = slice.len();
        let ptr = slice.as_mut_ptr();
    
        assert!(mid <= len);
    
        unsafe {
            (
                slice::from_raw_parts_mut(ptr, mid),
    //slice::from_raw_parts_mut获取一个raw pointer和一个length,然后创建对应的slice slice::from_raw_parts_mut(ptr.add(mid), len
    - mid), ) } }

     Unsafe-Call External Code

    比如从c的FFI(Foreign Function Interface)中调用函数,当然,程序员要负责对应的c library正确。

    extern "C" {
        fn abs(input: i32) -> i32;
    }
    
    fn main() {
        unsafe {
            println!("Absolute value of -3 according to C: {}", abs(-3));
        }
    }
    

      

    或者

    这里的#[no_mangle]是告诉Rust编译器不要对这个函数名做mangling操作,即给对应的用于编译的函数名

    #[no_mangle]
    pub extern "C" fn call_from_c() {
        println!("Just called a Rust function from C!");
    }
    

      

    Unsafe-修改静态变量

    static mut COUNTER: u32 = 0;
    
    fn add_to_count(inc: u32) {
        unsafe {
            COUNTER += inc;
        }
    }
    
    fn main() {
        add_to_count(3);
    
        unsafe {
            println!("COUNTER: {}", COUNTER);
        }
    }
    

      

    这里书中说明不变量和静态量的区别在于,静态量可能可以改变,此外,静态量的占空间大小是一定的,但是不变量可能会复制很多份。

    Unsafe-实现Unsafe特性

    unsafe trait Foo {
        // methods go here
    }
    
    unsafe impl Foo for i32 {
        // method implementations go here
    }
    
    fn main() {}
  • 相关阅读:
    Django模型-admin后台管理数据
    Django入门-登录(写死用户名、密码)
    Django-admin后台验证登录
    全面了解POI操作Microsoft Office(Word、Excel、PowerPoint)
    poi操作word 2007 常用方法总结
    submit text3常用快捷键
    c3p0配置详解
    c3p0参数解释
    log4j.properties 的使用详解
    TortoiseSVN文件夹及文件图标不显示解决方法(兼容Window xp、window7)
  • 原文地址:https://www.cnblogs.com/xuesu/p/13888598.html
Copyright © 2011-2022 走看看