0

I have the following very simple interfaces:

[uuid(0d585932-fbc4-4b0a-90b5-ccf34aefd4c6)] 
[version(COMPONENT_VERSION)] 
interface IPerson : IInspectable
{
    [propget] HRESULT Name([out, retval] HSTRING* value);
    [propput] HRESULT Name([in] HSTRING value);

    [propget] HRESULT Surname([out, retval] HSTRING* value);
    [propput] HRESULT Surname([in] HSTRING value);
}

[uuid(863571FC-4CBB-47E8-8BD3-2709D5CB7D0D)]
[version(COMPONENT_VERSION)]
interface ICitizen : IPerson 
{
[propget] HRESULT Address([out, retval] IAddress** value);
[propput] HRESULT Address([in] IAddress* value);
}

When I try to compile this MIDL for WinRT I get the following error:

error MIDL5004: interfaces must inherit from IInspectable : ICitizen

I'm really puzzled by what has become of COM under WinRT! How can we design application with that if such a simple thing as inheriting an interface from another is not possible any more?

I have searched for the documentation of the MIDL for WinRT and I couldn't find it!! Even better a search on google for error MIDL5004 doesn't show any result!

Could anyone from Microsoft explain how to create an interface that inherits from another one that inherits itself from IInspectable. In an another test I created the same interfaces with C++/CX and I'm able to create a ICitizen interface that inherits from IPerson. Why the MIDL of WinRT doesn't allow this anymore, this is the base of a COM architecture, creating a hierarchy of interfaces.

Thanks for your inputs O. Rouit

user1466502
  • 101
  • 2
  • 7

1 Answers1

4

All Windows Runtime interfaces must derive directly from IInspectable. Indirect derivation, by deriving from another Windows Runtime interface, is not possible.

Instead of using a derives-from relationship, you may use a requires relationship, using requires:

[uuid(863571FC-4CBB-47E8-8BD3-2709D5CB7D0D)]
[version(COMPONENT_VERSION)]
interface ICitizen : IInspectable
    requires IPerson 
{
    [propget] HRESULT Address([out, retval] IAddress** value);
    [propput] HRESULT Address([in] IAddress* value);
}

This requires relationship specifies that any type that implements the ICitizen interface must also implement the IPerson interface. The interfaces are independent, though, and have distinct (non-shared) vtables. The requires relationship is 1:M, so a single interface may require that any implementer also implement a set of M other interfaces.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • Btw, I suggest that you define your methods to take runtime classes, not interfaces. Also don't forget to run the .winmd file that is generated by MIDL through the mdmerge tool - if you don't do that, it won't be able to be consumed by C++/CX, C# or JS. – Larry Osterman Feb 02 '13 at 06:40
  • @LarryOsterman kindly shed more light why its better defining the method to take runtime classes _instead_ of interfaces ? IIRC, COM at the ABI layer deals only w/ interfaces (providing runtimeclass parameter is equivalent providing the __INonVirtualPublic i/f as parameter) – Shmil The Cat May 14 '17 at 10:55