If you use an implementation of TNonRefCountInterfacedObject, then document in the descendants how lifetime management is arranged for
Posted by jpluimers on 2021/01/21
There are a few TNonRefCountInterfacedObject
(or maybe better named TNonReferenceCountedInterfacedObject
) implementations around (see list of links below).
They can be used to expose interfaces, but do not provide interface reference counting. This means you have to do your own lifetime management, which can bring quite a few headaches.
So each class you descend from it must have proper motivation on why, and how lifetime management is performed.
One thing you can do is mark the class with a hint directive like [WayBack] library
.
In addition, [Archive.is] TNonRefCountInterfacedObject
/ [Archive.is] TNonReferenceCountedInterfacedObject
implementations should at least implement [WayBack] IInterface
(or [WayBack] IUnknown
in really old Delphi versions); I have seen implementations that don’t but just provide almost empty [WayBack] QueryInterface
, [WayBack] _AddRef
and [WayBack] _Release
methods).
Some examples via “TNonRefCountInterfacedObject” – Google Search:
- [WayBack] Plugin-System Version 3 – Delphi-PRAXiS
- [WayBack] Delphi Knowledge Base: Create an interfaced object with no automatic destruction
- [WayBack] create a base class with a non-reference counted implementation of IUnknown?
Delphi RTL/VLC/FMX
I used this GExperts Grep Search expression to find the entries below:
(_AddRef|_Release|QueryInterface)
Delphi itself has a few implementations of non-standard interface management that have good documentation on their use cases. So take a look at at least these before doing something odd with interface implementations yourself:
- [WayBack]
TAggregatedObject
inSystem
- This redirects all
IInterface
implementations to a controller - It does not implement
IInterface
itself, so a descendent must add the interface reference - Descendants are
TContainedObject
andTPropertyPageImpl
(the latter used byTActiveXPropertyPage
)
- This redirects all
- [WayBack]
TContainedObject
inSystem
- This redirects all
IInterface
implementations exceptQueryInterface
to a controller - Descendants are for instance
TSOAPHeaders
(viaTSOAPHeadersBase
) used byTSoapPascalInvoker
,TInvokableClass
andTRIO
, andTConnectionPoint
used byTConnectionPoints
- This redirects all
- [WayBack]
TInterfacedPersistent
inSystem.Classes
- This supports the notion of (potentially) being owned by another
TPersistent
. Classes likeTCollectionItem
,TFieldOptions
andTEditButton
implement this ownership behaviour. - When owned, then redirect reference counting to the owner (if that owner implements
IInterface
), but notQueryInterface
- When not owned, then it is effectively non-reference counted
- This supports the notion of (potentially) being owned by another
- [WayBack]
TComponent
inSystem.Classes
- This supports the notion of (potentially) being owned by another
TComponent
. Classes likeTComponent
andTCollectionItem
implement this ownership behaviour. - When owned, then redirects all
IInterface
calls to the owner (includingQueryInterface
).
- This supports the notion of (potentially) being owned by another
- [Archive.is]
TXPEditReaderStream
in DUnitXP_OTAEditorUtils
. It is largely undocumented. TXPInterfacedObject
in DUnitXPInterfacedObject
. It is largely undocumented too.
Not so good examples:
- [WayBack]
TCustomVariantType
inSystem.Variants
(which is basicallyTSingletonImplementation
with a lot of extra methods) - [WayBack]
TSingletonImplementation
inSystem.Generics.Defaults
(which is basically what mostTNonRefCountInterfacedObject
implementations do; this is sort of OK as it is meant to be used only in [WayBack]TCustomComparer<T>
and descendants that are supposed to be singletons). IUnknown
inWinapi.Ole2
(this whole unit is undocumented; the class only has virtual abstract methods; the unit – together withWinapi.OleCtl
– seems to be only meant to support the depcrecatedVcl.OleAuto
unit.)
And of course there is the standard implementation with proper multi-threading support:
- [WayBack]
TInterfacedObject
inSystem
There are quite a few classes that implement reference counting while descending from things like TComponent
, usually without the proper multi-threading support that TInferfacedObject
has:
- [WayBack]
TStreamedConnection
inDatasnap.Win.SConnect
- [WayBack]
TSocketDispatcherThread
inScktMain
- [WayBack]
TFDPhysManager
inFireDAC.Phys
- [WayBack]
TXPInterfacedObject
in DUnitXPInterfacedObject
- [WayBack]
TWeakReferencedObject
in DUnitXDUnitX.WeakReference
- [WayBack]
TVirtualWebDir
inWeb.Win.AdsTypes
- [WayBack]
TEventDispatchEx
inWebBrowserEx
- [WayBack]
TInvokableClass
inSoap.InvokeRegistry
- [WayBack]
TOleControl
inVcl.OleCtrls
- [WayBack]
TOleServer
inVcl.OleServer
- [WayBack]
TUtilsNoRefCount
inXml.Internal.AdomCore_4_3
Finally some classes that implement QueryInterface in different ways:
- [WayBack]
TCustomWrapper
inSystem.Bindings.CustomWrapper
- [WayBack]
TLocationWrapper
inSystem.Bindings.EvalProtocol
- [WayBack]
TNestedScope
inSystem.Bindings.EvalSys
- [WayBack]
TAbstractMemberInstance
and [WayBack]TVirtualObjectMemberInstance
inSystem.Bindings.ObjEval
- [WayBack]
TPresentedControl
inFMX.Controls.Presentation
- [WayBack]
TCommonCustomForm
inFMX.Forms
- [WayBack]
THTMLElementEventDispatch
inWebBrowserEx
- [WayBack]
TRawVirtualClass
and [WayBack]TVirtualInterface
inSystem.Rtti
- [WayBack]
TComObject
and [WayBack]TComObjectFactory
and [WayBack]TDispatchSilencer
inSystem.Win.ComObj
- [WayBack]
TEventDispatch
and [WayBack]TDelegatedOleControl
inSystem.Win.OleControls
- [WayBack]
TServerEventDispatch
and [WayBack]TOleServer
inSystem.Win.OleServers
- [WayBack]
TInvokableClass
inSoap.InvokeRegistry
- [WayBack]
TRIO
and [WayBack]TRIO.TRioVirtualInterface
inSoap.Rio
- [WayBack]
THTTPRIO
inSoap.SOAPHTTPClient
- [WayBack]
TLinkedRIO
inSoap.SOAPLinked
- [WayBack]
TOleLinkStub
inVcl.AxCtrls
- [WayBack]
TCustomForm
inVcl.Forms
- [WayBack]
TAutoDispatch
and [WayBack]TAutoObject
and [WayBack]TClassFactory
inVcl.OleAuto
- [WayBack]
- [WayBack]
TOleContainer
inVcl.OleCtnrs
- [WayBack]
TEventDispatch
inVcl.OleCtrls
- [WayBack]
TServerEventDispatch
inVcl.OleServer
–jeroen
Leave a comment