ID3D11DeviceChild
similarly to a few other related interfaces offers methods including:
- ID3D11DeviceChild::GetPrivateData – Get application-defined data from a device child.
- ID3D11DeviceChild::SetPrivateData – Set application-defined data to a device child and associate that data with an application-defined GUID.
- ID3D11DeviceChild::SetPrivateDataInterface – Associate an
IUnknown
-derived interface with this device child and associate that interface with an application-defined GUID.
SetPrivateDataInterface
option extends SetPrivateData
by adding COM reference management to application defined data. However there is no GetPrivateDataInterface
… A reasonable assumption is that it is a single collection of keyed application defined data so it is possible to read interface values using GetPrivateData
method. The behavior should have been documented to avoid confusion.
I would perhaps not have posted this if there was no additional aspect. If I could read my interface values attached by SetPrivateDataInterface
using GetPrivateData
method, should I expect the returned values to be IUnknown::AddRef
‘ed or not?
ID3D11DeviceChild* p = …
IUnknown* pUnknownA = …
p->SetPrivateDataInterface(__uuidof(MyKey), pUnknownA);
…
IUnknown* pUnknownB;
UINT nDataSize = sizeof pUnknownB;
p->GetPrivateData(__uuidof(MyKey), &nDataSize, &pUnknownB);
// QUES: pUnknownB is AddRef'ed or not?
It is indeed possible to retrieve the interface data. With no documented behavior I would expect no IUnknown::AddRef
to be done. Rationale: after all I am using the method from the pair which is not supposed to deal with interface pointers. An argument against is that even though taking a raw copy of pointer is not a big deal, in multi-thread environment it might so happen that the returned unreferenced pointer is gone and invalidated if a concurrent thread replaces the collection value and internal IUnknown::Release
on the pointer results in object disposal.
My guess on the behavior in part of COM referencing was incorrect: the API does do IUnknown::AddRef
. Also this behavior is documented in the DXGI section for IDXGIObject::GetPrivateData
method:
If the data returned is a pointer to an IUnknown, or one of its derivative classes, previously set by IDXGIObject::SetPrivateDataInterface, you must call ::Release() on the pointer before the pointer is freed to decrement the reference count.
Presumably the same behavior applies to APIs having no explicitly mentioned documented behavior, including ID3D11Device::GetPrivateData
method, ID3D12Object::GetPrivateData
method and other.