将新功能添加到现有COM接口是否会破坏其二进制兼容性?

时间:2012-02-13 09:28:53

标签: com

我想在COM接口上添加一个新方法,其中所有现有方法都保持不变,这会在此次更新之前破坏其与消费者的兼容性吗?

3 个答案:

答案 0 :(得分:5)

这取决于:如果这是一个内部未发布的界面,只要您控制与该界面交互的所有代码,您就可以随意更改它。

然而,一旦发布,规则就是严格的:每个接口都有自己的IID。您可以通过任何方式更改该界面 - 通过修改,添加或删除方法 - 它是一个全新的界面,并且需要一个新的IID。

但是:COM并不关心如何实现新接口:所以你可以让你的类实现它作为旧接口的派生,只需添加一个新方法,并让你的实现类实现派生,所以只要QI在被要求使用旧接口或新接口时返回合适的接口。

例如:

class IInterfaceOriginal: public IUnknown
{
public:
    ...
    // lots of methods
    ...
};

class IInterfaceUpdated: public IInterfaceOriginal
{
public:
    // Add just one additional method
    STDMETHOD(AdditionalMethod)(...) = 0;
};


class CImplementation: IInterfaceNew // this was IInterfaceOld
{
    // Also add implemention of AdditionalMethod somewhere here...

    HRESULT STDMETHODCALLETYPE QueryInterface( REFIID riid, void **ppvObject )
    {
        *ppvObject = NULL;
        if(riid == __uuidof(IUnknown)
        || riid == __uuidof(IInterfaceOriginal)
        || riid == __uuidof(IInterfaceUpdated)) // This is added
        {
            // Return a IInterfaceUpdated in response to a QI for either of IUnknown,
            // or the old or new interface. This works because in C++, any IInterfaceUpdaed
            // is also both of those two other interfaces.
            *ppvObject = static_cast<IInterfaceUpdated*>(this);
        }
        else
            return E_UNKNOWN;
        return ((IUnknown*)*ppvObject)->AddRef();
    }

    ...
}

所以,虽然你在技术上“添加另一个接口”,但实际上你在这里添加一些代码:只是定义一个从旧的接口派生的新接口,将你的类实现的接口改为新接口(并添加新方法的实现),最后更新QI以支持旧方法和新方法 - 为两者返回相同的接口(也为IUnknown返回)。

答案 1 :(得分:3)

它肯定会破坏派生接口,所以即使它看起来有用也不应该这样做。

相反,派生一个包含其他方法的新接口,并让客户端需要新IID的附加功能QI。

答案 2 :(得分:0)

只要附加新方法,COM接口应向后兼容。如果客户端应用程序想要使用新的COM接口,则必须更新头文件(C ++)或将引用(.NET)重新添加到新的COM接口。此外,如果更改COM接口而不更新IID,则可能需要重新启动操作系统。总之,它可以在不改变IID的情况下工作,但改变IID可能更“正确”。