send_fn_ptr_from_addr

Macro send_fn_ptr_from_addr 

Source
macro_rules! send_fn_ptr_from_addr {
    ($sig:ty, $var:expr) => { ... };
}
Expand description

This macro creates a Function Pointer that is Send and guaranteed to have the same representation in memory as a raw function pointer would. (Meaning its size is usize)

§Null

This will not cause undefined behavior if a null pointer is used to create the function pointer. Unlike ordinary rust function pointers this type supports null pointers. Attempting to call a null function pointer will panic.

§Safety

This macro has to be placed in an unsafe block, because it accepts an arbitrary pointer as well as usize. The pointer/usize is interpreted as an address to a function. Should the pointer/usize not in fact be the address of a function with the given signature then this macro causes undefined behavior immediately.

The safe version of this macro is sync_fn_ptr! which only accepts a rust function type.

§Example


use std::ffi::c_void;
use sync_ptr::send_fn_ptr_from_addr;
use sync_ptr::SendFnPtr;

extern "C" fn test_function() -> u64 {
    123456u64
}

fn some_function() {
    //usually you would get this address from ffi/dlsym/GetProcAddress.
    let some_address = test_function as *const c_void;
    let test_fn_ptr = unsafe { send_fn_ptr_from_addr!(extern "C" fn() -> u64, some_address) };
    //Type of test_fn_ptr is SendFnPtr<extern "C" fn() -> u64>
    std::thread::spawn(move || {
        assert_eq!(test_fn_ptr(), test_function());
    }).join().unwrap();
}