Recently, I came up with an idea when learning to call function pointers. I used template variable parameters to construct template functions so that I can call function pointers
#include<functional>
#include<Windows.h>
template<class T, class ...Args>
decltype(auto) ExecuteFunc(LPVOID f, Args&& ...args) {
if (f != nullptr) {
return std::function<T>((T*)f)(std::forward<Args>(args)...);
}
}
int main(){
ExecuteFunc<int(HWND, char*, char*, int)>(&MessageBoxA, (HWND)NULL, (char*)"Text", (char*)"caption", MB_OK);
return 0;
}
Although this code runs well, it seems a bit too long picture Is there a way to shorten the code?
I hope the code can be simplified to call.
ExecuteFunc<int>(&MessageBoxA, (HWND)NULL, (char*)"Text", (char*)"caption", MB_OK);
If you have some interesting ideas, please express them freely.
Supplementary description. Some of the answers misunderstood my question and changed the type of the argument, which apparently std::invoke doesn't do yet. Argument one is passed in as a function pointer address, not the name of an already exported function Example 2.
LPVOID FunAddr=&MessageBoxA;
int ret=ExecuteFunc<int>(FunAddr, (HWND)NULL, (char*) "Text", (char*) "caption", MB_OK);
int ret=ExecuteFunc<int> means that the return value of the function is of type int FunAddr is the address of a function where you can't directly give the symbolic name of the function the rest of the function's parameters
Also I know that FunAddr doesn't have any available type information, but the parameters given can extract this type information and splice it to T(int,int)
template<class T,class . .Args>
T ExecuteFunc(LPVOID f, Args&&... .args) {
}
Thank you to all our friends for your support and comments. Your enthusiastic comments have provided me with constructive help At the moment I have accepted a more simple answer, which meets my needs very well.
The code and examples are as follows
template<class T,class F, class ...Args>
inline decltype(auto) ExecuteFunc(F f, Args&&...args) {
return reinterpret_cast<T(*)(Args...)>(f)(args...);
}
Example
#include<Windows.h>
#include<iostream>
template<class T, class F, class ...Args>
inline decltype(auto) ExecuteFunc(F f, Args&&...args) {
return reinterpret_cast<T(*)(Args...)>(f)(args...);
}
int Add(int a, int b) {
return a + b;
}
int main(){
//1.
LPVOID funcptr = &Add;
std::cout << ExecuteFunc<int>(funcptr, 1, 2) << std::endl;
//2.
std::cout << ExecuteFunc<int>(Add, 3, 5) << std::endl;
//3.
ExecuteFunc<int>(MessageBoxA,(HWND)NULL, (char*)"Text", (char*)"caption", MB_OK);
return 0;
}