我需要开发一个专门的 CLR 分析器。CLR 探查器必须作为 COM 服务器实现ICorProfilerCallback
或当前最高 5 的较新版本来实现。探查器初始化发生在回调方法Initialize(IUnknown* pICorProfilerInfoUnk)
中。这使人们有机会对QueryInterface
提供的IUnknown
对象执行操作并获得指向ICorProfilerInfo
接口的指针。从 .NET 4.5 开始,有ICorProfilerInfo
、ICorProfilerInfo2
、ICorProfilerInfo3
和ICorProfilerInfo4
,每个新版本都提供附加功能。理想情况下,我想获得一个指向最新可用版本的指针,并让 vtables 找出真正的对象是什么。
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;
}
}
}
}
请注意,在所有情况下,指向返回接口的指针都是相同的变量m_pICorProfilerInfo
,其类型为CComQIPtr<ICorProfilerInfo>
。然后我在它上面调用方法,而忽略了实现该方法的对象的实际类型。
这让我想到了两个问题:
- 在 COM / ATL 上下文中,检索派生接口,将它们存储在上述父接口中,然后从中调用函数是否安全?
- 父接口显然不知道派生接口中的功能。如何检查指针是否是派生接口(例如
ICorProfilerInfo2
)并将其转换为此类?
在到目前为止的测试中,#1 通常看起来还可以。但我更愿意确认或建议。我对第 2 点更加不确定。例如,ICorProfilerInfo
有一个SetEnterLeaveFunctionHooks
功能,而ICorProfilerInfo2
有一个SetEnterLeaveFunctionHooks2
功能。我想做类似下面的伪代码:
if (m_pICorProfilerInfo IS ICorProfilerInfo2)
{
((ICorProfilerInfo2) m_pICorProfilerInfo)->SetEnterLeaveFunctionHooks2(...)
}
else
{
m_pICorProfilerInfo->SetEnterLeaveFunctionHooks(...)
}
任何关于如何实现这一点的建议将不胜感激。