У меня есть компонент C ++ WinRT, который является WinRtClassicComMix. Я хочу определить метод, который возвращает пользовательский класс через IAsyncOperation в вызывающий код C # или WinJS.
Все работает нормально, когда IAsyncAction используется без возвращаемого значения, но использование PPL create_async с автоматическим возвращаемым значением приводит к сбою компилятора VS 2012 и VS 2013.
Соответствующие детали:
Интерфейсы и классы определены в 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);
}
}
Соответствующий заголовочный файл:
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);
};
И 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;
}
Компиляция завершается сбоем компилятора VS C ++:
Ошибка 1 ошибка C1001: произошла внутренняя ошибка в
компилятор. c: \ program files (x86) \ Microsoft Visual Studio
11.0 \ vc \ include \ ppltasks.h 5513 1 MyControl
Причиной является строка, в которой create_async назначается автоматической переменной asyncOp. Я не могу определить эту переменную явно, так как я не могу определить правильный тип. 🙁 Вероятно, это должен быть тип hat, но ABI :: MyControl :: MyComponentColorTable * не может быть объявлен как ^, поскольку он не определен как класс WinRT, поэтому я предполагаю, что create_async здесь вообще нельзя использовать, но как тогда я могу создать и вернуть WinRT IAsyncOperation моего типа? Что нужно для MyComponentColorTable, чтобы его можно было передавать обратно через WinRT? И IAvatarComponentColorTable нельзя использовать в качестве возвращаемого типа, поскольку он [exclusiveto (AvatarComponentColorTable)]. 🙁
Задача ещё не решена.
Других решений пока нет …