PDA

View Full Version : Referencing Classes ByRef vs ByVal



SamT
12-03-2017, 06:22 PM
Saved From: http://dailydoseofexcel.com/?s=Terminating+Dependent+Classes

Rob Bruce December 30, 2007 at 11:55 am (http://dailydoseofexcel.com/archives/2007/12/28/terminating-dependent-classes/#comment-29661)

Your Parent properties are causing circular references. These don’t get cleared until the original process is reset. In effect, that’s a memory leak.
The VB workaround is an absolutely beautiful hack first demonstrated, I believe, by Bruce McKinney. First, change your internal variable for the parent object to a long. This is going to point to the object rather than refer to it. Then use the undocumented objptr and the hack objfromptr functions to convert the object to and from its pointer. This way you’re never storing an object reference, so the circular reference in not created.

In your child class
Option Explicit
'Code edited by SamT: http://www.vbaexpress.com
'12/03/2017 to remove non-VBA Characters and add """

Private m_lngParentPtr As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(dest As Any, Source As Any, ByVal bytes As Long)

The Parent property

Public Property Get Parent() As Class1
Set Parent = ObjFromPtr(m_lngParentPtr) 'Returns an object given its pointer.
End Property

Public Property Set Parent(obj As Class1)
m_lngParentPtr = ObjPtr(obj) 'Returns the Pointer of a given Object
End Property




This function reverses the effect of the ObjPtr function.

Private Function ObjFromPtr(ByVal pObj As Long) As Object
Dim obj As Object

'force the value of the pointer into the temporary object variable
CopyMemory obj, pObj, 4

'assign to the result (this increments the ref counter)
Set ObjFromPtr = obj

'manually destroy the temporary object variable
'(if you omit this step you’ll get a GPF!)
CopyMemory obj, 0&, 4
End Function


HTH
Rob

Paul_Hossler
12-05-2017, 08:36 AM
Interesting

I liked the link also

Now .... can you make it work in a 64 bit Office environment?

SamT
12-05-2017, 09:41 AM
I can't, I don't have a 64bit environment, but you should just have to change


Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(dest As Any, Source As Any, ByVal bytes As Long)

That might be as simple as using :dunno:
PtrRtlMoveMemory
or
PtrMoveMemory

I only posted it here so I could save this as a web page.