EDN Admin
Well-known member
Hi,
I will try to explain this as comprehensible and as precise as possible.<br/>
I want to create a C/C++ function that can call any __stdcall exported function from any DLL based on the given parameters. The return value of the called DLL function is not of interest. Until now, I thought to generalize a parameter like this:
<pre class="prettyprint" style=" struct p{ int size;
char* data;
};
typedef struct p Parameter; [/code]
and I made the function definition look like this:
<pre class="prettyprint" style=" void callDLLFunction(char* libraryName, char* functionName, Parameter* params, int paramsCount);[/code]
Also, Ive created a variadic function delegate to use when calling any __stdcall functions, like this:
<pre class="prettyprint" style=" typedef void __stdcall (*dllFunctionInvoker)(...);[/code]
The function will load the DLL <libraryName> using the <span style="text-decoration:underline
LoadLibrary Windows API function, afterwards will get a pointer to the <functionName> function found in this library by using the
<span style="text-decoration:underline GetProcAddress WinAPI function and afterwards it needs to call this function by using the upper delegate,
<span style="text-decoration:underline passing the given params before calling it .
The "passing the given params before calling it" part is the one thats troubleing me. One way of passing the params would be with assembly code, but I want to extend this function to support
an y calling convention, which would mean Id have to write assembly code for every calling convention I want it to use.
I want to avoid writing assembly code and instead somehow modify the delegate definition to support passing maybe an array or byte-arrays (char** - where each byte-array would represent a parameter) or to use something C/C++ specific, similar to variadic
function calling, but which would allow me to pass them one by one.
To express this even clearer, I will try to give an example. First, let me make the problem a little bit more particular. Lets say that I only want this for functions that would present one of these 3 parameters specification:
<pre class="prettyprint" style=" 1. int, short, char
2. short
3. double, float[/code]
Now the problem can be accomplished with normal variadic functions. Heres how the cpp code could look like in this case:
<pre class="prettyprint" style=" struct p
{
int size;
char* data;
};
typedef struct p Parameter;
typedef void __stdcall (*dllFunctionInvoker)(...);
void callDLLFunction(LPCSTR libraryName, LPCSTR functionName, Parameter* params, int paramsDefinitionType){
HINSTANCE libAddress = LoadLibrary(libraryName);
dllFunctionInvoker f = (dllFunctionInvoker)GetProcAddress(libAddress, functionName);
switch(paramsDefinitionType){
case 1:
f(*(int*)(params[0].data), *(short*)(params[1].data), *(char*)(params[2].data));
break;
case 2:
f(*(short*)(params[0].data));
break;
case 3:
f(*(double*)(params[0].data), *(float*)(params[1].data));
break;
default:
break;
}
}[/code]
As you can see, since the parameters specifications are finite, variadic functions work ok. But what I want is the same effect for any type of parameter specification, without assembly!
Is this possible?
Thank you in advance, Zozel
<br/>
<br/>
View the full article
I will try to explain this as comprehensible and as precise as possible.<br/>
I want to create a C/C++ function that can call any __stdcall exported function from any DLL based on the given parameters. The return value of the called DLL function is not of interest. Until now, I thought to generalize a parameter like this:
<pre class="prettyprint" style=" struct p{ int size;
char* data;
};
typedef struct p Parameter; [/code]
and I made the function definition look like this:
<pre class="prettyprint" style=" void callDLLFunction(char* libraryName, char* functionName, Parameter* params, int paramsCount);[/code]
Also, Ive created a variadic function delegate to use when calling any __stdcall functions, like this:
<pre class="prettyprint" style=" typedef void __stdcall (*dllFunctionInvoker)(...);[/code]
The function will load the DLL <libraryName> using the <span style="text-decoration:underline
LoadLibrary Windows API function, afterwards will get a pointer to the <functionName> function found in this library by using the
<span style="text-decoration:underline GetProcAddress WinAPI function and afterwards it needs to call this function by using the upper delegate,
<span style="text-decoration:underline passing the given params before calling it .
The "passing the given params before calling it" part is the one thats troubleing me. One way of passing the params would be with assembly code, but I want to extend this function to support
an y calling convention, which would mean Id have to write assembly code for every calling convention I want it to use.
I want to avoid writing assembly code and instead somehow modify the delegate definition to support passing maybe an array or byte-arrays (char** - where each byte-array would represent a parameter) or to use something C/C++ specific, similar to variadic
function calling, but which would allow me to pass them one by one.
To express this even clearer, I will try to give an example. First, let me make the problem a little bit more particular. Lets say that I only want this for functions that would present one of these 3 parameters specification:
<pre class="prettyprint" style=" 1. int, short, char
2. short
3. double, float[/code]
Now the problem can be accomplished with normal variadic functions. Heres how the cpp code could look like in this case:
<pre class="prettyprint" style=" struct p
{
int size;
char* data;
};
typedef struct p Parameter;
typedef void __stdcall (*dllFunctionInvoker)(...);
void callDLLFunction(LPCSTR libraryName, LPCSTR functionName, Parameter* params, int paramsDefinitionType){
HINSTANCE libAddress = LoadLibrary(libraryName);
dllFunctionInvoker f = (dllFunctionInvoker)GetProcAddress(libAddress, functionName);
switch(paramsDefinitionType){
case 1:
f(*(int*)(params[0].data), *(short*)(params[1].data), *(char*)(params[2].data));
break;
case 2:
f(*(short*)(params[0].data));
break;
case 3:
f(*(double*)(params[0].data), *(float*)(params[1].data));
break;
default:
break;
}
}[/code]
As you can see, since the parameters specifications are finite, variadic functions work ok. But what I want is the same effect for any type of parameter specification, without assembly!
Is this possible?
Thank you in advance, Zozel
<br/>
<br/>
View the full article