-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcall_method_by_ptr.rs
More file actions
50 lines (41 loc) · 1.28 KB
/
call_method_by_ptr.rs
File metadata and controls
50 lines (41 loc) · 1.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
use std::mem;
// Macro for cpp fans
macro_rules! reinterpret_cast {
($from:ty, $to:ty, $ptr:expr) => {
unsafe { mem::transmute::<$from, $to>($ptr) }
};
}
// "External" function
fn function_a(u: u32) -> u32 {
println!("i'm external function {u:?}");
0
}
// Structure that will record address of created function_a
struct Droppable {
ptr: *const u64,
}
// Implement Droppable::new to get address of function_a and write it to Droppable.ptr
impl Droppable {
fn new(function_a: *const u64) -> Droppable {
println!("> Create {function_a:?}");
Droppable { ptr: function_a }
}
}
// Overload Drop::drop by our own variant of the destructor for Droppable trait
// to output a message about freeing a specific address
impl Drop for Droppable {
fn drop(&mut self) {
println!("> Dropping {:?}", self.ptr);
}
}
fn main() {
// Function prototype definition
type Proto = extern "C" fn(u32) -> u32;
type Ptr = *const u64;
// Getting function_a pointer while destructor is running
let ptr_function_a: Droppable = Droppable::new(function_a as *const u64);
// Cast pointer to a function prototype
let function: Proto = reinterpret_cast!(Ptr, Proto, ptr_function_a.ptr);
// Calling a function by pointer
function(1337);
}