描述:
在看<<com原理与应用>>,有一段话不是很理解,请高手赐教!!!
一、
一个组件类CMy实现了两个接口IA、IB,它们都继承自接口IUnknown,在查询IUnknown接口时,我们先把this转换成IA 或者 IB 指针,再转换成IUnknown,但我们必须保证每次查到的IUnknown接口完全一致。
那么我就有点不明白了,为什么会返回相同的指针?我按书中的要求,在CMy::QueryInterface中
用 *ppv = (IUnknown *)(IA *)this
或 *ppv = (IUnknown *)(IB *)this ,它们的*ppv不一样,也就是说,获得的IUnknown接口不一致,该如何解释???
二、
类CMy实现了两个接口IA、IB,能不能说同时也实现了接口IUnknow?
三、
为什么每次用VC查看接口IA、IB时,只能看到接口IUnknow中的那三个函数?却看不到其它接口的函数?如何解释?
解决方案1:
其实你在实现QueryInterface是只要实现那5个规则就好了。
一般在将this指针值赋给某个void指针时,应先将其转换成合适的类型。一个有趣的例子是返回
IUnknown指针的情形。某些程序员可能会用:
*ppv = static_cast<IUnknown*>(this);
但是将this指针转换成IUnknown*是不明确的。这是由于IX和IY都是从
IUnknown继承得到的。
因此在这种情况下,返回值应该是
*ppv = static_cast<IUnknown*>(static_cast<IX*>(this)) 或者是
*ppv = static_cast<IUnknown*>(static_cast<IY*>(this))。
只不过在在上面,选择哪一个是无关紧要的,因为它们使用的都是同一实现。
但是在代码中要保持一致,因这两个指针实际上是不一样的,并且COM
要求对IUnknown接口返回相同的指针。
上面的话是《COM技术内幕——微软组件对象模型》书中的一段。
1是COM规范,目的是提供一个有效的方法来判断两个接口指针是否属于同一个COM对象实例,但其他接口指针不具此性质,甚至可以两次查询同一个接口而返回不同的值,比如teatoff接口。
解决方案4: 1 所谓“必须保证每次查到的IUnknown接口完全一致”指的是 *ppv的值(即返回值)相同。
2 对,这就是所谓的“菱形继承”了。
3 你的意思是说只有IUnknow的三个函数可以不查询直接调用,别的函数必须查询是吧?这是因为你是把*ppv作为 IUnknow* 来使用的。如果你直到*ppv的确切类型,直接调用它也是可以的。例如:
(IA*)*ppv->FA();
一、好象CMy::QueryInterface实现不是这样的吧。
这里假设IA为第一个继承的接口。
class CMy : public IA, public IB
{};
HRESULT CMy::QuerInterface(const IID& iid, void**ppv)
{
if(iid == IID_IUnknown)
{
*ppv = (IA*)this;//注意这里
((IA*)(*ppv))->AddRef();
}
else if(iid == IID_IA)
{
*ppv = (IA*)this;
((IA*)(*ppv))->AddRef();
else if(iid == IID_IB)
{
*ppv = (IB*)this;
((IB*)(*ppv))->AddRef();
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
return S_OK;
}
1 对于同一个对象的不同接口指针,查询得到的 IUnknown 接口必须完全相同。所以通过IA IB得到的IUnkown都是一个地址。这是COM接口的原则之一。
解决方案7: 1 不管转成什么类型,地址还是一样的。我不知道你怎么会认为*ppv的值会不同。
2 不行。
3 接口不是变量,不知道你是如何看到的。