uwpwinrt-xamluwp-xamlc++-winrtwinrt-component

InvalidCastException when calling wrt/c++ Windows Runtime Component from UWP Application C# project


I have a small solution that contains two projects:

The C++/WinRT component contains a class D3DPanel that is derived from Windows.UI.Xaml.Controls.SwapChainPanel. The code compiles, the control appears, and works fine when added to a page in the UWP C# App.

However, when I call the single void StartRenderLoop() method that my derived control exposes, I get:

System.InvalidCastException 'Unable to cast object of type 'WRT_CPP.D3DPanel' to type 'WRT_CPP.ID3DPanel'.'

   at System.StubHelpers.StubHelpers.GetCOMIPFromRCW_WinRT(Object objSrc, IntPtr pCPCMD, IntPtr& ppTarget)
   at WRT_CPP.D3DPanel.StartRenderLoop()
   at UWP_APP.MainPage.OnNavigatedTo(NavigationEventArgs e)

Here's the idl code:

namespace WRT_CPP
{
    [default_interface]
    runtimeclass D3DPanel : Windows.UI.Xaml.Controls.SwapChainPanel
    {
        D3DPanel();

        void StartRenderLoop();
    }
}

This is how the implementation class is declared:

struct D3DPanel : Windows::UI::Xaml::Controls::SwapChainPanelT<D3DPanel>
{
   ...
   void StartRenderLoop();
   ...
}

(The reason I know the control works, is that if I call StartRenderLoop() from within the WinRT component during OnLoaded everything looks fine).

The (almost) minimal version of the source code can be found at: https://github.com/zrajnai/UWP_DX

To reproduce the problem comment out the call to StartRenderLoop from within the C++/Winrt code at: https://github.com/zrajnai/UWP_DX/blob/227226e8dfbaf2b9b6ce78b6eb02c727c197e284/WRT_CPP/D3DPanel.cpp#L332

and uncomment the line that throws the exception: https://github.com/zrajnai/UWP_DX/blob/227226e8dfbaf2b9b6ce78b6eb02c727c197e284/UWP_APP/MainPage.xaml.cs#L19

Any help is appreciated.


Solution

  • The problems was in the implementation class

    struct D3DPanel : Windows::UI::Xaml::Controls::SwapChainPanelT<D3DPanel>
    

    I should have added ID3DPanel as a generic parameter as well as the implementation class itself.

    struct D3DPanel : Windows::UI::Xaml::Controls::SwapChainPanelT<D3DPanel, ID3DPanel>