代码
#[no_mangle]
// extern "C" fn using(f: extern "C" fn()) {
extern "C" fn using(f: *const u8) {
let a = (&f) as *const _ as *const fn();
let b = unsafe { *a };
println!("DLL开始");
b();
println!("DLL结束");
}
extern "C" fn a() {
println!("a()...");
}
#[no_mangle]
extern "C" fn DllMain(hinstDLL: *mut u8, reason: u32, reserved: *mut u8) -> u32 {
match reason {
1 => {
// DLL_PROCESS_ATTACH
println!("连接到进程!");
intro();
}
0 => {
// DLL_PROCESS_DETACH
println!("检测到进程退出");
}
_ => (),
}
return 1;
}
fn intro() {
let p = a as extern "C" fn ();
println!("p -> {:p}.", p); // 该地址正确,不过类型是fn()
let p = &a as *const _ as *const u8;
println!("p -> {:p}.", p); // 似乎是临时变量的地址
let p = &(a as extern "C" fn ()) as *const _ as *const *mut u8;
println!("p -> {:p}.", p); // 这个肯定是临时变量的地址,因为解引用之后正是a函数的地址
println!("p -> {:p}.", unsafe { *p }); // a函数正确的地址
unsafe {
using(*p); // 该函数接收的是一个C函数的地址
}
}