C++ CLR探查器:COM风格的从派生接口转换和调用函数
我需要开发一个专门的CLR分析器。CLR探查器必须作为COM服务器实现C++ CLR探查器:COM风格的从派生接口转换和调用函数,c++,com,atl,clr-profiling-api,C++,Com,Atl,Clr Profiling Api,我需要开发一个专门的CLR分析器。CLR探查器必须作为COM服务器实现ICorProfilerCallback或当前升级到5的更新版本。探查器初始化在回调方法初始化(IUnknown*pICorProfilerInfoUnk)中进行。这使您有机会对提供的IUnknown对象执行QueryInterface,并获取指向ICorProfilerInfo接口的指针。从.NET 4.5开始,共有ICorProfilerInfo、ICorProfilerInfo2、ICorProfilerInfo3和IC
ICorProfilerCallback
或当前升级到5的更新版本。探查器初始化在回调方法初始化(IUnknown*pICorProfilerInfoUnk)
中进行。这使您有机会对提供的IUnknown
对象执行QueryInterface
,并获取指向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_picorprofileinfo
,其类型为CComQIPtr
。然后我调用它的方法,而不知道实现该方法的对象的实际类型
这就引出了两个问题:
icorprofileinfo2
),并将其强制转换为派生接口ICorProfilerInfo
有一个SetEnterLeaveFunctionHooks
函数,而ICorProfilerInfo2
有一个SetEnterLeaveFunctionHooks2
函数。我想做一些类似于以下伪代码的事情:
if (m_pICorProfilerInfo IS ICorProfilerInfo2)
{
((ICorProfilerInfo2) m_pICorProfilerInfo)->SetEnterLeaveFunctionHooks2(...)
}
else
{
m_pICorProfilerInfo->SetEnterLeaveFunctionHooks(...)
}
任何关于如何实现这一点的建议都将不胜感激。1)对于这些接口类型来说是可以的,它们被精心设计以始终继承以前的版本。因此,ICorProfilerInfo4的v表包含了之前3个版本的所有方法。这当然不一定总是COM接口的情况,但在这里是可行的。这是危险的,当您获得ICorProfilerInfo3接口时调用ICorProfilerInfo4方法将使您的程序崩溃。你没有得到编译器的帮助来避免麻烦
2)C++中没有IIS操作符,可以通过调用QueYrIdFACE()调用COM。或者,您可以设置一个变量,指示您获得的接口版本。使用QI可以避免在版本检查错误时发生崩溃,并允许编译器帮助您正确地获取代码
我建议您首先对实际需要的分析器功能进行分类。您可能会增加太多的灵活性,这种灵活性会让您编写永远不会使用的代码,并发布一个未经充分测试的程序。FunctionEnter2和FunctionEnter3之间的区别并不微妙,但两者都可以正常工作,您不太可能注意到优化。感谢您的回复。我决定使用CComQIPtr并检查NULL来实现IS/AS。关于灵活性的观点。虽然这可能仍然是一种内部工具,用于协助开发和QA,因此风险较小(尽管仍然很重要)。