1.C Variable length parameter
The parameter list for the frequently used C-language function, printf, contains a description string for the const char*, and a variable-length parameter (...), as follows for the function declaration of printf.
int printf (const char * __restrict, ...)
In Stdarg.h This header file contains some macros that operate on variable length parameters (for example, the x86 platform):
#define VA_START (AP,V) (AP = (va_list) &v + _intsizeof (v))
#define VA_ARG (Ap,t) (* (t *) (AP + = _intsizeof (t))-_intsizeof (t)))
#define VA_END (AP) (AP = (va_list) 0)
Where running Va_start (AP, V) can cause the AP to point to the address of the first parameter of a variable-length parameter list. Where V is the last fixed parameter.
Va_arg (AP,T) points the AP to the next parameter of a variable-length parameter list, and uses the input type T for data-strong conversions, returning a user-required parameter value.
Va_end (AP), the set AP is null.
Detailed variable length parameter explanation see this blog: Imjacob's column--c in the language of printf implementation
Universal call function for Lua in 2.C language
1#include <stdarg.h>2 3 voidCall_va (Const Char* Func,Const Char*Sig,...)4 {5Va_list VL;//defines a variable-length parameter pointer with no initial value6 intNarg;//number of variable-length parameters7 intNres;//number of return values for LUA functions8 9Va_start (Vl,sig);//to point the pointer to the first parameter of the variable-length parameter first addressTenLua_getglobal (L,func);//function into the stack One A //---parameters into the stack - for(narg=0; *sig;narg++)//Traversal Parameters - { the //check the stack for space -Lual_checkstack (L,1,"Too many arguments"); - - Switch(*sig++) + { - //according to the constraint character of the parameter, by type into the stack, d-double i-int s-char* + Case 'D': ALua_pushnumber (L,va_arg (VL,Double)); at Break; - Case 'I': -Lua_pushinteger (L,va_arg (VL,int)); - Break; - Case 's': -Lua_pushstring (L,va_arg (VL,Char*)); in Break; - Case '>': to //end of input parameter + GotoEndargs; - default: theError (L,"Invalid option (%c)", * (sig-1)); * } $ }Panax Notoginseng //---parameters into the stack - Endargs: theNres=strlen (SIG);//expected number of LUA function return values + A //Calling Lua functions the if(Lua_pcall (L,narg,nres,0)!=0) + { -Error (L,"error calling '%s ':%s", Func,lua_tostring (l,-1)); $ } $ - //The return value retrieved after the call - //The Stack index is -1,-2,-3 from the top of the stack, so the stack index of the first result is-nres thenres=-nres; - while(*Sig)Wuyi { the //get the type descriptor for the return value in turn *sig - Switch(*sig++) Wu { - Case 'D': About if(!Lua_isnumber (l,nres)) $Error (L,"wrong result type"); -*va_arg (VL,Double*)=Lua_tonumber (l,nres); - Break; - A Case 'I': + if(!Lua_isnumber (l,nres)) theError (L,"wrong result type"); -*va_arg (VL,int*)=Lua_tointeger (l,nres); $ Break; the the Case 's': the if(!lua_isstring (l,nres)) theError (L,"wrong result type"); -*va_arg (VL,Const Char**)=lua_tostring (l,nres); in Break; the the default: AboutError (L,"Invalid option (%c)", * (sig-1)); the } the //parameter index of the result +1 thenres++; + } - Va_end (VL); the Bayi}
Thus, if we need to invoke a LUA function, we only need the following invocation form:
Call_va ("func", "Dd>ds", x,y,&z,&s);
The function named Func, which represents this LUA function, accepts two double, returns a double and a string, ' > ' represents the delimiter for the parameter and the result of the return value.
C variable-length parameters use-----to write generic calling functions for LUA