Can I destroy a class instance even if there are still references?
-
05-10-2019 - |
Question
For debugging reasons I want to destroy a class instance which still as references. Is that possible? It doesn't have to be elegant or stable, because this'll never end up in production code.
To clarify:
Public Sub Main
Dim o as MyClass
Set o = New MyClass //o is created, one reference
DestroyObject o //Class_Terminate is called and the object destroyed
//Further code, not using o
End Sub //Possible runtime error here (don't care)
Is that possible? One way would be to call IUnknown::Release
to manually decrease the reference count, but how do I now how often I must call it?
Solution
This is a very bad idea
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private m_oRef As Class1
Private Sub Command1_Click()
Dim o As Class1
Set o = New Class1
Set m_oRef = o
DestroyObject o
' releasing m_oRef after this point will bring down the IDE '
End Sub
Private Sub DestroyObject(pArg As Object)
Dim lRefCount As Long
Dim lIdx As Long
Dim pUnk As IUnknown
lIdx = ObjPtr(pArg) + &H20
Call CopyMemory(lRefCount, ByVal lIdx, 4)
For lIdx = 1 To lRefCount - 2
Call CopyMemory(pUnk, pArg, 4)
Set pUnk = Nothing
Next
Set pArg = Nothing
End Sub
OTHER TIPS
As you know, the object itself will call Class_Terminate
when it thinks its reference count has got to zero, so your suggestion of calling Release
should do the trick - just keep calling Release
until Release
itself throws an error.
This page from Bruce McKinney's Hardcore Visual Basic suggests one possible way that it might sometimes be possible to get the reference count, but I don't think you need to get into that unless this scheme (of Release
ing till you can't Release
no more) doesn't work.
"this'll never end up in production code" - careful with your assumptions, of course...