Reputation: 17
I need to call a function where I have the LPVOID and the number of arguments. Furthermore I know the types and positions of the arguments. The arguments can be of type int, int*, double, double*, string, string*. As the arguments can be in any order the possible list of templates would be very large. The return value is always boolean.
bool Func1(int);
bool Func1(int*);
bool Func1(double);
(...)
bool Func2(int,int);
bool Func2(int,int*);
(...)
So this is not an option. I've tried to use std::tuple but with no success. The following examples only works for a function with arguments (int, double).
template <typename R, typename... Args>
R call(FARPROC fp, Args... args) throw(HRESULT)
{
typedef R(__stdcall * function_pointer)(Args...);
function_pointer P = (function_pointer)fp;
const auto return_value = (*P)(std::forward<Args>(args)...);
().do_cast(fetch_back(args))...);
return return_value;
}
(...)
LPVOID function;
int iVal1 = 2;
double dbVal1 = 3.0;
auto t = std::make_tuple(iVal1 , dbVal1);
bool bRes = call<bool>((FARPROC)function, std::get<0>(t), std::get<1>(t));
What I am thinking about is a generic way of creating the std::tuple based on some input (string etc.), something like: auto t = create_tuple("int,int*,int").
Upvotes: 0
Views: 1168
Reputation: 2090
My suggestion, for anyone interested in alternatives...
Bury the LPVOID function under a meaningful API and never use it directly again.
Obviously, an LPVOID function taking a bunch of void *ters is not self-documenting, so provide something that is.
Provide various constructors or helper methods that accept the values required for making a specific low level call to the LPVOID and provide conversion methods for handing the values down to the LPVOID.
Upvotes: 0
Reputation: 988
I have a proposal but you must set double
variables through its address, like a pointer, because a double variable has 8 bytes meanwhile void pointer's size has 4 bytes for x86 and 8 bytes for x64. Also string
variables must be setted as pointers:
#include "stdafx.h"
#include <string>
using namespace std;
bool Func1(void* arg1, void* arg2, void* arg3, void* arg4, void* arg5, void* arg6)
{
bool result = false;
int a1 = (int)arg1;
int a2 = *(int*)arg2;
double a3 = *(double*)arg3;
double* a4 = (double*)arg4;
string a5 = *(string*)arg5;
string* a6 = (string*)arg6;
//Do something...
return result;
}
int main()
{
bool(*myFun)(void* arg1, void* arg2, void* arg3, void* arg4, void* arg5, void* arg6);
myFun = &Func1;
int a1 = 2;
int a2 = 3;
double a3 = 4;
double* a4 = new double(5);
string a5= "MyData 1";
string* a6 = new string("MyData 2");
bool r = (*myFun)((void*)a1, (void*)&a2, (void*)&a3, (void*)a4, (void*)&a5, (void*)a6);
return 0;
}
I hope this could help you.
Upvotes: 0