study_example/advance_feature/
unsafe_rust.rs

1use core::slice;
2
3/// 运行结果如下
4/// ```txt
5/// r1 is 10
6/// r2 is 10
7/// thread 'main' panicked at 'misaligned pointer dereference: address must be a multiple of 0x4 but is 0x12345', study-example/src/advance_feature/unsafe_rust.rs:11:9
8/// note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
9/// ```
10fn define_raw_pointer() {
11    let mut num = 10;
12    let r1 = &num as *const i32;
13    let r2 = &mut num as *mut i32;
14    let address = 0x012345usize;
15    let r = address as *const i32;
16
17    unsafe {
18        println!("r1 is {}", *r1);
19        println!("r2 is {}", *r2);
20        // println!("r is {}", *r);
21    }
22}
23
24/// 如果不在unsafe代码块执行则会编译时出现如下错误
25/// error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
26///  --> study-example/src/advance_feature/unsafe_rust.rs:27:9
27///    |
28/// 27 |         dangerous();
29///    |         ^^^^^^^^^^^ call to unsafe function
30unsafe fn dangerous() {}
31
32/// error[E0499]: cannot borrow `*values` as mutable more than once at a time
33/*fn split_at_mut(values: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) {
34    let len = values.len();
35    assert!(mid <= len);
36    (&mut values[..mid], &mut values[mid..])
37}*/
38
39fn split_at_mut(values: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) {
40    let len = values.len();
41    let ptr = values.as_mut_ptr();
42    assert!(mid <= len);
43    unsafe {
44        (
45            slice::from_raw_parts_mut(ptr, mid),
46            slice::from_raw_parts_mut(ptr.add(mid), len - mid),
47        )
48    }
49}
50
51/// 运行结果如下
52/// ```txt
53/// a: [1, 2, 3]
54/// b: [4, 5, 6]
55/// ```
56fn create_safe_abstract_over_unsafe_code() {
57    let mut v = vec![1, 2, 3, 4, 5, 6];
58    let r = &mut v[..];
59    // split_at_mut中调用了不安全的函数from_raw_parts_mut,但是assert!(mid <= len);保证了范围说明指针式安全的
60    let (a, b) = split_at_mut(r, 3);
61    println!("a: {:?}", a);
62    println!("b: {:?}", b);
63}
64
65// 调用C的对应函数签名的函数,C是比较常见的ABI
66extern "C" {
67    fn abs(input: i32) -> i32;
68}
69
70// 将 call_from_c 函数编译为共享库并从 C 链接后,从 C 代码访问该函数:
71#[no_mangle]
72pub extern "C" fn call_from_c() {
73    println!("Just call a Rust function from C!");
74}
75
76static HELLO_RUST: &str = "Hello, Rust!";
77static mut COUNTER: u32 = 0;
78fn add_to_count(inc: u32) {
79    unsafe {
80        COUNTER += inc;
81    }
82}
83
84unsafe trait Foo {
85    // method signature
86}
87
88unsafe impl Foo for i32 {}
89
90/// 运行结果如下
91/// ```txt
92/// Absolute value of -3 according to C: 3
93/// COUNTER: 3
94/// global static string: Hello, Rust!
95///
96pub fn unsafe_rust_study() {
97    define_raw_pointer();
98    add_to_count(3);
99    unsafe {
100        dangerous();
101        println!("Absolute value of -3 according to C: {}", abs(-3));
102        println!("COUNTER: {}", COUNTER);
103    }
104    create_safe_abstract_over_unsafe_code();
105    println!("global static string: {}", HELLO_RUST);
106}