Quantcast
Channel: VBForums - CodeBank - Visual Basic 6 and earlier
Viewing all articles
Browse latest Browse all 1448

[VB6] VB6.tlb - Passing a ParamArray without Copying

$
0
0
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.

edit: After a a good amount of fumbling, I using Curland's proven methods, with my own self modfying code.
I usually avoid assembly, and dislike mixing it with VB - but here's the cleaned up routines.

just include MParamArray.bas in a project, and you can use the GetParams function.
GetParams takes a single Parameter Offset, and returns a Variant Array, that you can use to pass to other functions.
GetParams steals the Array reference off the stack, without copying the original Array.

Code:

' SomeForm.frm or Class1.cls
Private Sub Func1(ParamArray Params())
    ' NOTE: offset calculation from Frame Pointer in a Class Module (.cls) or Form (.frm)
    ' saved ebp (4) + return address (4) + this ptr (4) + No Params before ParamArray (0)
    OtherFunc GetParams(12)
End Sub

Code:

' StandardModule.bas
Private Sub Func2(ParamArray Params())
    ' NOTE: offset calculation from Frame Pointer (ebp) in a Standard Module (.bas)
    ' saved ebp (4) + return address (4) + no other params on stack before ParamArray (0)
    Dim ParamOffset As Long: ParamOffset = 4 + 4 + 0
    If InIDE Then ParamOffset = ParamOffset + 4 ' Standard Module Functions need an extra 4 bytes when debugging

    'If you need to pass the array as a ParamArray, to allow modification of ByRef paramaters, Use CallPtr
    CallPtr AddressOf Module1.OtherFunc, vbEmpty, RefAry(GetParams(ParamOffset))
End Sub

Attached Files

Viewing all articles
Browse latest Browse all 1448

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>