The Issue: How do you access a ParamArray, and pass it to another function,
without copying it.
The Answer: Pointer magic. ParamArrays are really just a
Variant Array - managed by the runtime. For whatever reason though - the
runtime / ide doesn't allow you to get at it's address easily, or even pass it
to another function without making a copy
This particular technique I believe was first pioneered by Matt Curland.
Originally Curland used assembly to get the stack pointer,
add a hard coded offset (depending on the function parameters passed before
the ParamArray) to calculate where the SAFEARRAY** is on the stack, then
return the dereferenced pointer. Then you can safely swap the SAFEARRAY
reference with another SAFEARRAY.
Really though - it 's as simple as using a typelib defined __vbaRefVarAry.
Why does it have to be in a typelib? I don't know, but the side effect is
that the runtime marshals the ParamArray ByRef into a VARIANT, without
creating a copy first. This is not typically allowed by the IDE. I haven't
verified if this only applies to midl generated typelibs vs mktyplib.
Anyway... here's the code. Feel free to run it through a debugger to verify
that the ParamArray is indeed not copied.
edit: Should have done my homework... seems to still make a copy.
This can is tested by passing a variable (which passes ByRef in the ParamArray) and then modifying it.
It should modify the original Variable.
without copying it.
The Answer: Pointer magic. ParamArrays are really just a
Variant Array - managed by the runtime. For whatever reason though - the
runtime / ide doesn't allow you to get at it's address easily, or even pass it
to another function without making a copy
This particular technique I believe was first pioneered by Matt Curland.
Originally Curland used assembly to get the stack pointer,
add a hard coded offset (depending on the function parameters passed before
the ParamArray) to calculate where the SAFEARRAY** is on the stack, then
return the dereferenced pointer. Then you can safely swap the SAFEARRAY
reference with another SAFEARRAY.
Really though - it 's as simple as using a typelib defined __vbaRefVarAry.
Why does it have to be in a typelib? I don't know, but the side effect is
that the runtime marshals the ParamArray ByRef into a VARIANT, without
creating a copy first. This is not typically allowed by the IDE. I haven't
verified if this only applies to midl generated typelibs vs mktyplib.
Anyway... here's the code. Feel free to run it through a debugger to verify
that the ParamArray is indeed not copied.
edit: Should have done my homework... seems to still make a copy.
This can is tested by passing a variable (which passes ByRef in the ParamArray) and then modifying it.
It should modify the original Variable.