The argument-constructor functions in dispargs.c place argument information in global arrays.
int g_iArgCount;
int g_iNamedArgCount;
VARIANTARG g_aVargs[MAX_DISP_ARGS];
DISPID g_aDispIds[MAX_DISP_ARGS + 1];
LPOLESTR g_alpszArgNames[MAX_DISP_ARGS + 1];
WORD g_awFlags[MAX_DISP_ARGS];
The Vargs array contains the argument values; the lpszArgNames array contains the argument names (unnamed arguments have NULL names); and the wFlags array contains argument flags (such as NOFREEVARIANT). The information in these arrays is used to build the argument list for an IDispatch interface call. The arrays in dispargs.c are statically allocated to reduce complexity; this places a limit on the number of arguments that can be passed. To remove this limit and manage memory more effectively, the code could be modified to allocate memory dynamically.
When the Invoke function is called, it uses the IDispatch::GetIDsOfNames function to convert the names in the lpszArgNames array into DISPID values for the IDispatch::Invoke function. The resulting DISPID values are placed in the DispIds array. The first element of the DispIds array is the DISPID of the method or property, and the first element of the lpszArgNames array is the method or property name.