Search code examples
windows-runtimec++-cxwinrt-component

Public ref class implementing internal interface in C++/CX


I have a Windows Runtime component in which all of my classes need to expose a handle internally:

private interface class IHandleContainer {
    IntPtr GetHandle();
}
namespace Foo {
    public ref class Bar: IHandleContainer { ... }
    public ref class Baz: IHandleContainer { 
    internal:
        virtual IntPtr GetHandle() = IHandleContainer::GetHandle;
    }
}

I don't need IHandleContainer to be public, but I do need IHandleContainer to be on the interface list so that each of my internal objects can be safe_cast<IHandleContainer> successfully.

Being outside of a namespace, IHandleContainer should not be emitted to metadata, but should have a COM GUID associated with it and by listing it on the ref class's interface list, CX should be able to wire up the correct response to QueryInterface. Structurally, everything should "just work." But the compiler isn't cooperating:

error C3991: 'Foo::Baz': cannot implement a non-public or nested interface 'IHandleContainer'

Solution

  • Unfortunately this is not possible using C++/CX, and none of the tricks you might try will work.

    • Interface members can't be internal
    • There is no such thing as internal inheritance
    • public WinRT types can't derive from private bases
    • WinRT types can't derive from non-WinRT types
    • public WinRT types can't be unsealed unless they derive from something that is unsealed

    That last one is recursive, and the only way out of it is to derive from an existing unsealed platform-provided type like DependencyObject, but you really don't want to do that.

    You need to use something CloakedIid in WRL, or Kenny Kerr's pure C++ example on MSDN Magazine. Either way you have to define your types in IDL and implement them the "hard" way.