Let's say we have a type FARPROC
that we receive as result of certain Win32 operations, such as GetProcAddress
. It's definition is as follows:
pub type FARPROC = unsafe extern "system" fn() -> isize;
This type then needs to be converted to a valid function type so we can call it. As developers, we know the function signature (from documentation), but we need to pass that knowledge onto the compiler. A straightforward approach is to use transmute
with explicit function type as following:
let address: FARPROC = unsafe { GetProcAddress(module, proc).unwrap() };
let function: extern "system" fn(i32) = unsafe { transmute (&address) };
But what if we wanted to infer the function type from one of the existing functions that we defined in our rust code? Let's say we have some function with lengthy definition:
pub fn foo(arg1: i32, arg2: c_void, arg3: *const c_char) {
// snip
}
In order to keep our code DRY, is it possible to use that function type with transmute
?
My attempted solution looks like the following snippet:
pub fn cast_to_function<F>(address: FARPROC, _fn: &F) -> F {
unsafe { transmute_copy(&address) }
}
/// Usage
let address: FARPROC = unsafe { GetProcAddress(module, proc).unwrap() };
let function = cast_to_function(address, &foo);
function(1, ...);
This attempted solution is based on the similar C++ code that is working:
template<typename T>
T FnCast(void* fnToCast, T pFnCastTo) {
return (T)fnToCast;
}
/// Usage
void bar(int arg1, void* arg2, const char* arg3){
// snip
}
auto address = (void*) GetProcAddress(...);
auto function = FnCast(address, &bar);
function(1, address, "bar");
The problem with my attempted solution in rust is that cast_to_function
always returns the function with address that points to the referenced function, rather than an address that points to the one which we provided. Hence, given what was laid out so far, is it possible to intelligently infer the function type from its definition and cast arbitrary type to it?