COM+架构的基本思想
——实现IUnknown::QueryInterfacce方法时的规则
注:这是我早年的笔记,已经忘记了从哪儿摘抄的了
注:这是我早年的笔记,已经忘记了从哪儿摘抄的了
对象必须支持静态接口聚集
可以通过QueryInterfacce访问的接口聚集必须是静态的而不是动态的。如果对指定接口指针的一个QueryInterfacce调用而言,第一次成功了,那么以后的调用也肯定成功;如果第一次失败了,那么以后的所有尝试也将失败。
假设给定一个对象的IUnknown接口指针为pUnknown,那么下列代码肯定能成功执行。
ISum *pSum1 = 0;
ISum *pSum2 = 0;
// Ask the object(referenced by pUnknown) for any one
// interface pointer two times
HRESULT hr1 = pUnknown->QueryInterface(IID_Sum, (void**)&pSum1);
HRESULT hr2 = pUnknown->QueryInterface(IID_Sum, (void**)&pSum2);
// Both attempts must either succeed of fail
if( !(SUCCEEDED(hr1) == SUCCEEDED(hr2)) )
cout<<"Error: Object must support a static set of interfaces."<<endl;
//Release the reference added by QueryInterface
if( SUCCEEDED(hr1) == SUCCEEDED(hr2) )
{
pSum1->Release();
pSum2->Release();
}
IUnknown必须是唯一的
对于IUnknown接口指针的每个客户请求,QueryInterface都必须总是能够返回其完全一致的内存地址。意即总是可以通过比较两个对象的IUnknown接口指针来确定两个指针是否指向同一对象;如果它们都指向同一地址,那么它们也就引用了同一对象。
假定某对象IUnknown接口指针为pUnknown,则下列代码肯定能成功执行。
IUnknown *pUnknown1 = 0;
IUnknown *pUnknown2 = 0;
// Ask the object(referenced by pUnknown) for any one
// interface pointer two times
HRESULT hr1 = pUnknown->QueryInterface(IID_IUnknown, (void**)&pUnknown1);
HRESULT hr2 = pUnknown->QueryInterface(IID_IUnknown, (void**)&pUnknown2);
// Both attempts must succeed
if( FAILED(hr1) || FAILED(hr1) )
cout << "Error: IUnknown must always be available." << endl;
// The two pointer values must be indentical
if( pUnknown1 != pUnknown2 )
cout << "Error: Object indentity rule have been violated!" << endl;
//Release the reference added by QueryInterface
...
QueryInterface必须是反身的
如果客户拥有一个接口指针并进行查询同一接口的指针,则该调用能成功。
ISum *pSum1 = 0;
ISum *pSum2 = 0;
// Ask the object for an interface pointer
HRESULT hr1 = pUnknown->QueryInterface(IID_Sum, (void**)&pSum1);
if( SUCCEEDED(hr1) )
{
// Assuming that was successful, ask for the same interface
// using the interface pointer referred above
HRESULT hr2 = pUnknown->QueryInterface(IID_IUnknown, (void**)&pUnknown2);
// The second request for the same interface must also succeed
if( FAILED(hr2) )
cout << "Reflexive rule of QueryInterface violated!" << endl;
//Release the reference added by QueryInterface
pSum1->Release();
if( SUCCEEDED(hr2) )
pSum2->Release();
}