I'll agree that it introduces too many problems and should be avoided, especially if the code needs to be portable.
However, if absolutely necessary, there's the option to create a stack, then pass the pointer off to a va_arg() call. The stack can be made by testing SvNOK, SvPOK, or SvIOK and incrementing the pointer accordingly. Some compilers want a pointer that increments, others want pointers that de-increment. On retrieval, the format string indicates how the va_arg should be taken off the stack (int, char, double).
This example is the clearest thing I've found on forged va_lists. It also explains how the alignment can cause problems: