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

Tho*_*son 4 com

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

Bre*_*McK 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();
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

所以,当你在技术上"增加一个接口",实际上是在这里添加一些代码:只是限定从旧派生的新界面,改变你的类实现到新的接口(以及增加对实施新方法),最后更新QI以支持旧方法和新方法 - 为两者返回相同的接口(对于IUnknown也是如此).