winrt-asyncc++-winrt

How to fix 'the arguments to the parameterized interface are not valid' error of IDL file in WinRT?


I'm getting "the arguments to the parameterized interface are not valid" error when trying to write IDL file for my Windows Runtime Component class.

The RunAsync() function returns winrt::Windows::Foundation::IAsyncOperation in my header and I translated it to winrt.Windows.Foundation.IAsyncOperation as https://learn.microsoft.com/en-us/uwp/winrt-cref/winrt-type-system states that UInt32 is "fundamental type" and "[WinRT fundamental types] are permitted to appear in the argument list for a parameterized type".

//ConnectTask.idl
namespace NOVAShared
{
    [default_interface]
    runtimeclass ConnectTask
    {
        ConnectTask();
        winrt.Windows.Foundation.IAsyncOperation<UInt32> RunAsync();
    };
}
//ConnectTask.h
namespace winrt::NOVAShared::implementation
{
    struct ConnectTask : ConnectTaskT<ConnectTask>
    {
        ConnectTask() = default;

        static winrt::Windows::Foundation::IAsyncOperation<uint32_t> RunAsync();
    };
}

Is my syntax wrong? I've found some random examples of IDL files and it seems right...


Solution

  • The error message of the MIDL compiler is a fair bit misleading. When you compile the following IDL file

    namespace NS
    {
        runtimeclass MyType
        {
            foo<UInt32> bar();
        }
    }
    

    you'll get this error message:

    error MIDL5023: [msg]the arguments to the parameterized interface are not valid [context]: foo
    

    However, it's not the argument that's invalid. It's the parameterized type (foo) that's unknown. In your case that's winrt.Windows.Foundation.IAsyncOperation. A type with that name does not exist. The Windows Runtime type name is Windows.Foundation.IAsyncOperation instead (which gets projected into the winrt namespace in C++/WinRT, i.e. winrt::Windows::Foundation::IAsyncOperation).

    To fix the issue, use the following IDL file:

    //ConnectTask.idl
    namespace NOVAShared
    {
        [default_interface]
        runtimeclass ConnectTask
        {
            ConnectTask();
            Windows.Foundation.IAsyncOperation<UInt32> RunAsync();
        };
    }
    

    Note that if you want a static class member, you will have to use the static keyword in IDL.