分析可变参数需要了解函数调用栈的使用:
1)函数调用约定
2)调用栈的生长和其内容
1、函数调用约定
为什么只有__cdecl的调用约定支持可变参数,而__stdcall就不支持?
__cdecl和__stdcall函数参数都是从右到左入栈,它们的区别在于由谁来清栈,__cdecl由外部调用函数清栈,而__stdcall由被调用函数本身清栈, 显然对于可变参数的函数,函数本身没法知道外部函数调用它时传了多少参数,所以没法支持被调用函数本身清栈(__stdcall), 所以可变参数只能用__cdecl.
2、函数参数传递过程中堆栈的生长
从堆栈低地址到高地址,依次存储:
1)被调用函数局部变量
2)上一函数堆栈桢基址
3)函数返回地址
4)参数1, 参数2, 参数3
函数调用时,参数2的地址就是参数1的地址加上参数1的长度,而参数3的地址是参数2的地址加上参数2的长度,以此类推。
3、可变参数分析
(1)简单可变参数
测试可变参数的函数, 代码如下:int Sum(int nCount, )
{
int nSum = 0;
int* p = &nCount;
for(int i=0; i<nCount; ++i)
{
cout << *(++p) << endl;
nSum += *p;
}
cout << "Sum:" << nSum << endl << endl;
return nSum;
}
string SumStr(int nCount, )
{
string str;
int* p = &nCount;
for(int i=0; i<nCount; ++i)
{
char* pTemp = (char*)*(++p);
cout << pTemp << endl;
str += pTemp;
}
cout << "SumStr:" << str << endl;
return str;
}
int main()
{
Sum(3, 10, 20, 30);
SumStr(5, "aa", "bb",