我今天在我的代码中遇到了一个问题,通过将我的 COM 对象转换为 IUnknown** 导致了访问冲突,AFAICT。它传入的函数执行没有问题,但是当调用我的对象的一个函数时,它会执行一些随机函数并破坏堆栈然后死。
指示性代码(忽略为什么这样做 - 我知道它很糟糕,我知道如何修复它,但这是为什么会出现这样的问题的问题):
void MyClass2::func(IMyInterface* pMyObj)
{
CComPtr<IMyInterface2> pMyObj2;
HRESULT hRes = pMyObj->GetInternalObject((IUnknown**)&pMyObj2);
if (SUCCEEDED(hRes))
pMyObj2->Function(); // corrupt stack
}
void MyClass::GetInternalObject(IUnknown** lpUnknown)
{
pInternalObject->QueryInterface(IID_IMyInterface2, (void**)lpUnknown);
}
我一直对在 COM 对象上使用 C/C++ 强制转换有点怀疑,但直到现在我从未遇到过(可能是通过未定义的行为)任何问题。
我快速浏览了一下,据我所知,只要继承链中没有多重互斥,转换为 IUnknown 在技术上是有效的,但这不是最佳实践——我真的应该将 IUnknown 传递给MyClass::GetInternalObject(IUnknown** lpUnknown)
然后查询返回我想要的界面的价值。
我的问题是,是否有关于何时可以在 COM 对象上使用 C/C++ 转换的规则,除了多重继承和它们带来的调整器 thunk 之外,转换 COM 对象如何导致访问冲突等意外?请详细说明。
编辑:它们都是应该如何正确完成的很好的例子,但我希望的是一个技术解释为什么你不应该转换 COM 对象(假设存在)例如转换将在情况x下返回 pMyObj2-4但是QueryInterface 将返回 pMyObj2-8 因为y ...或者转换 COM 对象只是一个不好的做法/风格的问题?
TIA