Click here to Skip to main content
15,885,956 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hello,

Once again, I would like to ask you something.
I have exported function:
DoSomething(LPSTR lpszFormat, ...)


But I need to call this function with variable count of arguments during runtime.
Let's say some of my function generated some DWORDs. And they are supposed to be passed to DoSomething.
So: lpszFormat is now "ddd" -> This mean there will be 3 DWORDs passed to this function. But how can I actually call DoSomething("ddd", DWORD1, DWORD2, DWORD3); during runtime?

I think I can handle this problem easily with ASM (The format would be read and the values would be PUSHed to stack), but how can I do it with C++?

Thank you for your answers.
Posted
Updated 12-May-10 4:12am
v3

Here is something I got from MSDN
int average( int first, ... )
{
   int count = 0, sum = 0, i = first;
   va_list marker;

   va_start( marker, first );     /* Initialize variable arguments. */
   while( i != -1 )
   {
      sum += i;
      count++;
      i = va_arg( marker, int);
   }
   va_end( marker );              /* Reset variable arguments.      */
   return( sum ? (sum / count) : 0 );
}
 
Share this answer
 
you may use va_start, va_arg, va_end [^].
:)
 
Share this answer
 
I actually meant something like this:

DoSomething is function exported from other DLL.

In my application:

{
...
int nDataType = 0;
int nCount = ListBox.GetCount(); //Obtains number of items
for ( int i = 0; i < nCount; i++)
{
    nDataType = GetDataType(ListBox.GetText(i, someCString); //
    switch(nDataType)
    {
        //Now Create format from cases -> Let's say I have 5 items 
        // BYTE, DWORD, BYTE, DWORD, STRING
        // The LPSTR lpszFormat will be after loop "bdbds"
    }
}
...
/*And now I need to call the DoSomething("bdbds", thatBYTE, thatDWORD, thatByte, thatDWORD, thatSTRING);
*/


}


I cannot modify the code of DoSomething. I just need to call it with various informations, which are collected from ListBox. I hope it's more clear what I'm trying to achieve now.

It's something like
for(blahblah)
{
switch(TYPE)
case DWORD:
mov eax, CurSelData;
push eax;
break;

case BYTE:
mov eax, CurSelData:
push eax;
break;
...
}
// I know I highly abstracted that


and then after the loop the stack would be looking for example like:
ptrToFormat // "dbds"
data1 //(DWORD)
data2 //(BYTE)
data3 //(DWORD)
data4 //(STRING)

and then

call DoSomething



EDIT:
One guy told me, that it's not possible to do it with C++. So I made it with combining C++ and ASM.
 
Share this answer
 
v3
You don't need any stinking assembly language. All you have to do is get the data on the stack. Now this is not portable, but near enough on all the platforms I use:

C++
int *p = (int *)_alloca( 12 );
p[ 0 ]  = 1;
p[ 1 ]  = 2;
p[ 2 ]  = 3;
std::printf( "%d\n%d\n%d\n" );


If you're using a Unixy OS you might have to use alloca rather than _alloca.

Cheers,

Ash
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900