变参函数定义形式如func(type a, ...),要求至少一个固定参数,由于须要经过这个参数来肯定究竟有多少个参数、以及参数的类型。 windows
windows中,变参函数用来获取参数的几个宏定义以下。 函数
typedef char * va_list; #define _ADDRESSOF(v) ( &(v) ) #define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) ) #define va_start(ap,v) ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) ) #define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) #define va_end(ap) ( ap = (va_list)0 )
_ADDRESSOF的做用是获取数据的地址,_INTSIZEOF是获取指定类型数据按照int类型对齐的空间大小,va_start就是根据第一个参数来获取第二个参数,va_arg是根据当前参数获取第二个参数。经过这种方法能获取到参数的缘由是参数是从右到左依次压入栈的,而且栈是从高地址向低地址生长的,这两个条件决定了能够使用这种方法获取参数。 spa
返回地址 |
h |
g |
f |
e |
d |
c |
b |
a |
|
如上图所示,当调用func(a, b, c, d, e, f, g, h)时,参数会从高地址向低地址压入参数,参数是从右向左的顺序压栈的,第一个参数的地址加上第一个参数的大小便获得了第二个参数的地址,以此类推即可以获得各个参数的地址。
code