I have a need to develop a specialized CLR profiler. CLR profilers must be implemented as a COM server implementing ICorProfilerCallback or a newer version currently up through 5. Profiler initialization occurs in a callback method Initialize(IUnknown* pICorProfilerInfoUnk). This gives one an opportunity to do a QueryInterface on the provided IUnknown object and obtain pointers to the ICorProfilerInfo interfaces. As of .NET 4.5, there are ICorProfilerInfo, ICorProfilerInfo2, ICorProfilerInfo3, and ICorProfilerInfo4, with each new version providing additional functionality. Ideally I would like to obtain a pointer to the latest available version and let the vtables figure out what the real object is.
if (FAILED(pICorProfilerInfoUnk->QueryInterface(IID_ICorProfilerInfo4, (LPVOID*)&m_pICorProfilerInfo)))
{
if (FAILED(pICorProfilerInfoUnk->QueryInterface(IID_ICorProfilerInfo3, (LPVOID*)&m_pICorProfilerInfo)))
{
if (FAILED(pICorProfilerInfoUnk->QueryInterface(IID_ICorProfilerInfo2, (LPVOID*)&m_pICorProfilerInfo)))
{
if (FAILED(pICorProfilerInfoUnk->QueryInterface(IID_ICorProfilerInfo, (LPVOID*)&m_pICorProfilerInfo)))
{
AtlTrace(TEXT("[Initialize] Failed to retrieve any ICorProfilerInfo~ interface."));
return S_FALSE;
}
}
}
}
Notice that all cases, the pointer to the returned interface is the same variable m_pICorProfilerInfo, which is of type CComQIPtr<ICorProfilerInfo>. I then call methods on it oblivious of the actual type of the object implementing the method.
This leads me to two questions:
- In COM / ATL context, is it safe to retrieve derived interfaces, store them in a parent interface such as above, and then call functions from it?
- A parent interface obviously has no knowledge of functions in derived interfaces. How can I check if the pointer IS A derived interface (such as
ICorProfilerInfo2) and cast it to such?
In testing so far, #1 generally seems okay. But I would would prefer confirmation or advise. I am much more uncertain about point #2. For example, ICorProfilerInfo has a SetEnterLeaveFunctionHooks function while ICorProfilerInfo2 has a SetEnterLeaveFunctionHooks2 function. I would like to do something like the following pseudo code:
if (m_pICorProfilerInfo IS ICorProfilerInfo2)
{
((ICorProfilerInfo2) m_pICorProfilerInfo)->SetEnterLeaveFunctionHooks2(...)
}
else
{
m_pICorProfilerInfo->SetEnterLeaveFunctionHooks(...)
}
Any advice on how can this be accomplished would be most appreciated.