WinRT WRL WinRtClassicComMix and IAsyncOperation fails

1k views Asked by At

I have a C++ WinRT component which is a WinRtClassicComMix. I want to define a method which returns a custom class through an IAsyncOperation to the calling C# or WinJS code. All is working fine when an IAsyncAction is used with no return value, but using PPL's create_async with an auto return value crashes the VS 2012 and VS 2013 compiler.

The relevant details:

The interfaces and classes are defined in IDL:

namespace MyControl
{
    runtimeclass MyComponentColorTable;
    [version(MyS_VERSION)]
    [uuid(7BB5A348-C82C-4EC4-946F-5113843A6A83)]
    [exclusiveto(MyComponentColorTable)]
    interface IMyComponentColorTable: IInspectable
    {
        [propget] HRESULT Count([out, retval] unsigned long  *value);
        HRESULT GetAt([in] unsigned long index, [out, retval] ComponentColor  *componentColor);
    }

    [version(MyS_VERSION)]
    [activatable(MyS_VERSION)]
    [marshaling_behavior(agile)]
    [threading(both)]
    runtimeclass MyComponentColorTable
    {
        [default] interface IMyComponentColorTable;
    }

    runtimeclass MyRendererScene;
    [version(MyS_VERSION)]
    [uuid(8D51F7F2-EDCF-4ED4-B556-03D3CC390A83)]
    [exclusiveto(MyRendererScene)]
    interface IMyRendererScene: IInspectable
    {
        HRESULT GetComponentColorTableAsync([in] GUID assetId, [out, retval] Windows.Foundation.IAsyncOperation<MyControl.MyComponentColorTable*>** operation);
    }
}

The corresponding header file:

class CMyRendererScene :
    public Microsoft::WRL::RuntimeClass
    <
       RuntimeClassFlags<Microsoft::WRL::WinRtClassicComMix>,
       IMyRendererScene
    >
{
    InspectableClass(RuntimeClass_MyControl_MyRendererScene, BaseTrust);

public:
    CMyRendererScene(void);
    ~CMyRendererScene(void);

    IFACEMETHOD(GetComponentColorTableAsync)(GUID assetId, ABI::Windows::Foundation::IAsyncOperation<ABI::MyControl::MyComponentColorTable*>** operation);
};

And the CPP:

IFACEMETHODIMP CMyRendererScene::GetComponentColorTableAsync(GUID assetId, ABI::Windows::Foundation::IAsyncOperation<ABI::MyControl::MyComponentColorTable*>** operation)
{
    Concurrency::task_completion_event<ABI::MyControl::MyComponentColorTable*> tce;
    auto tsk = Concurrency::create_task(tce);
    auto asyncOp = Concurrency::create_async( [tsk]() -> Concurrency::task<ABI::MyControl::MyComponentColorTable*> 
    {
        return tsk;
    });

    // ... Wrapping of the event-based model using task_completion_event happens here ...

    return S_OK;
}

Compiling this fails with a crash of the VS C++ compiler:

Error 1 error C1001: An internal error has occurred in the compiler. c:\program files (x86)\microsoft visual studio 11.0\vc\include\ppltasks.h 5513 1 MyControl

The reason is the line where create_async is assigned to the asyncOp auto variable. I fail to define that variable explicitly since I can't figure out the right type. :( It probably needs to be a hat type, but ABI::MyControl::MyComponentColorTable* can't be declared as ^ since it's not defined as WinRT class, so I assume create_async can't be used at all here, but how can I create and return a WinRT IAsyncOperation of my type then? What is needed for MyComponentColorTable so it can be passed back through WinRT? And IAvatarComponentColorTable can not be used in the as the return type since it's [exclusiveto(AvatarComponentColorTable)]. :(

0

There are 0 answers