Search notes:

VBA classes: reference counting

As per Michael Rutten's Hidden Gems for Free, a regular Visual Basic object stores is reference count at the memory location right after its VTable pointer.
This is demonstrated with the following class. Its member function objRefCnt gets the ref count from the second DWORD in the object (whose address of the first DWORD is found with objPtr).
Apparently, passing an object to a function increases its reference count by two which is why 2 is subtracted before returning the reference count.

cntRef.bas

option explicit

private declare sub RtlMoveMemory lib "kernel32" alias "RtlMoveMemory" ( _
   dest  as     any    , _
   src   as     any    , _
   byVal nbytes as long)


function objRefCnt(obj as IUnknown) as long ' {

  ' debug.print "objPtr(obj) = " & objPtr(obj)

    if not obj is nothing then
    '
    '  Apparently, an object's ref Count is pointed at by the
    '  second member in a VB COM object:
    '
       RtlMoveMemory objRefCnt, byVal objPtr(obj) + 4, 4
       objRefCnt = objRefCnt - 2
    else
       objRefCnt  = 0
    end if

end function ' }
Github repository about-VBA, path: /language/classes/reference-counting/cntRef.bas

Foo.cls

Foo is a simple class which we will use below in the test.
option explicit
Github repository about-VBA, path: /language/classes/reference-counting/Foo.cls

test.bas

A simple test.
option explicit

sub main()

    dim obj_1 as Foo
    dim obj_2 as Foo

    debug.print objRefCnt(obj_1) ' 0

    set obj_1 = new Foo
 '  debug.print "objPtr(obj_1) = " & objPtr(obj_1)
    debug.print objRefCnt(obj_1) ' 1

    set obj_2 = obj_1
    debug.print objRefCnt(obj_1) ' 2
    debug.print objRefCnt(obj_2) ' 2

    set obj_2 = new Foo
    debug.print objRefCnt(obj_1) ' 1
    debug.print objRefCnt(obj_2) ' 1

end sub
Github repository about-VBA, path: /language/classes/reference-counting/test.bas

See also

IUnknown

Index