變參函數定義形式如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