Search code examples
c++-winrtwinrt-component

WinRT C++ component with non primitive function return types fails to compile/build


The below program works fine while having functions with primitive return type functions specifically the Pop function defined below works and I'm able to build properly, but when I build the solution with a function having non primitive return type as in PopC like below project doesn't build, but definitions are syntatically correct and I'm able to see the types being referred properly with proper namespace definitions in pch.h file.

Have defined the below code in the StreamSamplePool.idl file,

    namespace WinRTComponent
    {
    [default_interface]
    runtimeclass StreamSamplePool
    {
        StreamSamplePool();
        Int32 MyProperty;
       // MediaStreamSample PopC();
        Int32 Pop();
    }
    }

And inside the StreamSamplePool.cpp file have defined the respective methods as follows

        #include "pch.h"
        #include "StreamSamplePool.h"
        #include "StreamSamplePool.g.cpp"
        #include <stack>
        #include <queue>
        using namespace winrt::Windows::Storage::Streams;
        using namespace  winrt::Windows::Foundation;
        using namespace std;
        //using namespace Platform;
        using namespace  winrt::Windows::Media::Core;
    
        namespace winrt::WinRTComponent::implementation
        {
        int32_t StreamSamplePool::MyProperty()
        {
            throw hresult_not_implemented();
        }
        int32_t StreamSamplePool::Pop()
        {
            return int32_t();
        }
        //MediaStreamSample StreamSamplePool::PopC()
        //{
        //    MediaStreamSample sample = MediaStreamSample::CreateFromBuffer(NULL, 
         //TimeSpan());
        //    //sample.Processed += OnSampleProcessed;
        //    return sample;
        //}
        void StreamSamplePool::MyProperty(int32_t /* value */)
        {
            throw hresult_not_implemented();
        }
        }

And have defined the following code inside StreamSamplePool.h

        namespace winrt::WinRTComponent::implementation
        {
        struct StreamSamplePool : StreamSamplePoolT<StreamSamplePool>
        {
            StreamSamplePool() = default;
    
    
            int32_t Pop();
    
            //MediaStreamSample PopC();
    
            int32_t MyProperty();
            void MyProperty(int32_t value);
        };
        }
    
        namespace winrt::WinRTComponent::factory_implementation
        {
        struct StreamSamplePool : StreamSamplePoolT<StreamSamplePool, 
       implementation::StreamSamplePool>
       {
       };
       }

Error info

Error MIDL2011 [msg]unresolved type declaration [context]: WinRTComponent.MediaStreamSample [ Procedure 'PopC' ( RuntimeClass 'WinRTComponent.StreamSamplePool' ) ] WinRTComponent D:\Prithvi\Work\WinRTComponent\StreamSamplePool.idl 9

Compiler output

1>D:\...\StreamSamplePool.idl(9): error MIDL2011: [msg]unresolved type declaration [context]: WinRTComponent.MediaStreamSample [ Procedure 'PopC' ( RuntimeClass 'WinRTComponent.StreamSamplePool' ) ]
1>Done building project "WinRTComponent.vcxproj" -- FAILED.


Solution

  • The issue can be reduced to the following IDL file:

    namespace WinRTComponent
    {
        [default_interface]
        runtimeclass StreamSamplePool
        {
            StreamSamplePool();
            MediaStreamSample PopC();
        }
    }
    

    Compiling this using a default-generated C++/WinRT Component project produces the following error:

    1>C:\...\StreamSamplePool.idl(7): error MIDL2011: [msg]unresolved type declaration [context]: WinRTComponent.MediaStreamSample [ Procedure 'PopC' ( RuntimeClass 'WinRTComponent.StreamSamplePool' ) ]

    It contains all the information required to resolve the issue. In particular it's naming the error ("unresolved type declaration"), and the procedure affected ("PopC"). To solve this you'll have to provide the fully-qualified type name in the IDL file, i.e.

    namespace WinRTComponent
    {
        [default_interface]
        runtimeclass StreamSamplePool
        {
            StreamSamplePool();
            Windows.Media.Core.MediaStreamSample PopC();
        }
    }
    

    With that done, go to the "Generated Files\sources" directory under the project root, and copy the respective parts of the "StreamSamplePool.h" and "StreamSamplePool.cpp" files that the build system generated to your source files.