Как вернуть массив asyc, написав компонент среды выполнения Windows на C ++ / WinRT

Каков наилучший способ асинхронного возврата массива из компонента среды выполнения Windows, написанного на C ++ / WinRT, учитывая, что IAsyncOperation ‹TResult› не допускается в качестве возвращаемого типа, если TResult является массивом?

Можно обернуть массив в PropertyValue, но как упаковка, так и распаковка массива создают копии, что кажется неэффективным. На данный момент я пишу специальный компонент для хранения com_array (у которого есть конструктор, который позволяет мне перемещаться в com_array) с функцией DetachArray, которая перемещает массив при возврате к вызывающей стороне. Это лучший способ - он кажется немного сложным? Кроме того, в этом случае, если я вызываю функцию DetachArray из C #, копируется ли массив или нет? Я не знаю, как работает взаимодействие между управляемой и неуправляемой памятью. Я предполагаю, что использование com_array в отличие от std :: vector как-то связано с этим.


person Ben Stevens    schedule 25.10.2019    source источник


Ответы (1)


TResult IAsyncOperation, который необходимо передать, относится к типу среды выполнения Windows. Если вы хотите вернуть массив, вы можете попробовать использовать Windows::Foundation::Collections::IVector как объект коллекции вместо winrt :: com_array. В этом случае это будет удобно и не нужно упаковывать и распаковывать. Например:

Windows::Foundation::IAsyncOperation<Windows::Foundation::Collections::IVector<hstring>> Class::MyMethod()
{
    Windows::Foundation::Collections::IVector<hstring> coll1{ winrt::single_threaded_vector<hstring>() };
    ......
    co_return coll1;
}
person Faywang - MSFT    schedule 28.10.2019
comment
Спасибо за ответ. Однако я хочу вернуть массив, а не объект среды выполнения Windows, потому что мне нужен доступ к нему, чтобы он работал эффективно и не вовлекал взаимодействие. Это будет большой массив байтов - может быть, до 100 МБ, поэтому я ищу наиболее эффективный метод. Также я надеюсь, что кто-то сможет ответить на мой вопрос о том, копируется ли массив. - person Ben Stevens; 28.10.2019
comment
Что насчет перемещения массива? Вы имеете в виду, что использовали метод std :: move ()? И не могли бы вы показать более подробную информацию о том, как вы сохранили com_array и функцию DetachArray? - person Faywang - MSFT; 30.10.2019
comment
Реализация выглядит так: CustomByteArray :: CustomByteArray (com_array ‹uint8_t› && givenBytes) {swap (givenBytes, bytes); } com_array ‹uint8_t› CustomByteArray :: DetachArray () {com_array ‹uint8_t› temp {}; своп (байты, темп); возвратная температура; } Есть закрытый член com_array ‹uint8_t›, называемый 'bytes'. com_array имеет удаленный конструктор копии, поэтому он будет возвращен перемещением. - person Ben Stevens; 30.10.2019
comment
Если вам нужен байтовый массив, вы можете использовать IBuffer. В противном случае DetachArray, похоже, пытается выжать максимум из плохой ситуации. - person Faywang - MSFT; 06.11.2019