Will adding a new function to an existing COM interface break its binary compatibility?

I want to add a new method to the COM interface with everything existing without changes, will this violate its compatibility for the consumer before this update?

+4
source share
3 answers

It depends: if it is an internal unpublished interface, you can modify it as you wish, as long as you manage all the code that interacts with this interface.

After publication, however, the rules are strict: each interface has its own IID. You are changing this interface in any way - by changing, adding, or deleting methods - this is a completely new interface and requires a new IID.

However: COM does not care about how this new interface is implemented: therefore, you can implement your class as the output of the old interface, which simply adds a new method, and let your implementation class implement the output, therefore, since QI returns the appropriate interface when requesting either the old one, or a new interface.

For instance:

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(); } ... } 

So, while you technically “add another interface”, you actually add a little code here: just define a new interface obtained from the old one, change the interface that your class implements to the new one (and add the implementation for the new method) and finally QI update to support both old and new methods - return the same interface for both (and for IUnknown).

+5
source

This will probably break the derived interfaces, so it should not be done even if it works.

Instead, output a new interface containing additional method (s), and you have clients who need additional QI functionality for the new IID.

+3
source

As long as a new method is added, the COM interface must be backward compatible. If the client application wants to use the new COM interface, it needs to update the header file (C ++) or re-add the link (.NET) to the new COM interface. In addition, you may need to restart the OS if the COM interface is changed without updating the IID. In conclusion, it will work without changing the IID, but it may be more “correct” to change the IID.

0
source

Source: https://habr.com/ru/post/1396159/


All Articles