You all may use the Supports routine - so did I without further thinking about it - until today. I shamefully have to admit that I should have looked at its code and/or the documentation earlier.
What happened? In my bindings I check the source and target objects for special interfaces (f.i. INotifyPropertyChanged). I changed some code and strange things started happening in form of access violations. So I quickly found out that the Supports call caused a Destroy on the object when it did not support the given interface. Looking at the source revealed why: Supports does not only call GetInterface with the given guid, no it also does it for IUnknown causing _AddRef and _Release calls. And we know how that ends on some refcounted object that has the initial refcount of 0.
Actually there is a comment saying: "NOTE: Calling this overload on a ref-counted object that has REFCOUNT=0 will result in it being freed upon exit from this routine." And the documentation says: "Warning [...] For objects that have a reference count of zero, this will result in the object destruction."
Just another reason why Delphi sometimes is a pain in the ass if you are using object references and interfaces. Some may say: "Just use interfaces!" No, I do not want to write interfaces for simple data objects and other things. But I want to use interfaces for certain aspects (f.i. INotifyPropertyChanged). And most important: I do not want my objects getting destroyed if they DO NOT implement the requested interface.
Actually I have no idea why this was implemented like this long ago. Anyway I wrote my own Supports overload now:
function Supports(const Instance: TObject; const IID: TGUID; out Intf): Boolean;
begin
Result := Assigned(Instance) and Instance.GetInterface(IID, Intf);
end;
If your instance is assigned for sure you just might call the GetInterface method. I know there might be cases where the other Supports returns true and this one not like when having a customized QueryInterface. But in my cases it should solve my problem of instances getting shot in the head by the Supports call.
Let me know if I missed something about this implementation.