0

私は現在、いくつかのテキストリソースを必要とするメトロアプリケーションに取り組んでいます。ビルドプロセスの一部は、これらのリソースのすべてを、アプリケーションのインストールディレクトリ内のフォルダにコピーすることです。私がしたいことは、これらのリソースファイルのリストを収集し、それに応じてそれぞれのリソースファイルを処理することです。残念なことに、そうする私の試みは成功していません。C++でのWinRT非同期ファイル操作

私はWinRT用にビルドしているので、非常に便利な "FindFirstFile"と "FindNextFile"関数を使用することはできません。私は、WinRT非同期ファイル入出力操作を使用してジョブを完了しようとしています。

コンパイルに失敗し
auto getResourceFolder = installedLocation->GetFolderFromPathAsync( folderPath ); 

getResourceFolder->Completed = ref new Windows::Foundation::AsyncOperationCompletedHandler<Windows::Storage::StorageFolder^>( 
[this](Windows::Foundation::IAsyncOperation<Windows::Storage::StorageFolder^>^ operation) { 

    if(operation->Status == Windows::Foundation::AsyncStatus::Completed) { 

     auto resourceFolder = operation->GetResults(); 
     auto getResourceFiles = resourceFolder->GetFilesAsync(); 
     getResourceFiles->Completed = ref new Windows::Foundation::AsyncOperationCompletedHandler< IVectorView<Windows::Storage::IStorageFile^>^ >( 
     [this](Windows::Foundation::IAsyncOperation< IVectorView<Windows::Storage::IStorageFile^>^ >^ operation) { 

      if(operation->Status == Windows::Foundation::AsyncStatus::Completed) { 

       auto resourceFiles = operation->GetResults(); 

       for(unsigned int i = 0; i < resourceFiles->Size; ++i) { 

        // Process File 
       } 

      } 

     }); 

    } 

}); 

エラーC2664: 'Windowsの::財団:: IAsyncOperation < TResult> ::完了::設定':「のWindowsからパラメータ1を変換することはできません::財団:: AsyncOperationCompletedHandler < TResult>^Windowsの」から '::財団:: AsyncOperationCompletedHandler < TResult> ^'

はエラーが私には何の意味を行っていません。私はラムダハンドラ関数がインラインではないが、違いは生じていないように上記のコードを書き直そうとしました。私は何が間違っているのか分かりません。

アイデア?前もって感謝します。

+1

'do 'と 'then()'メソッドを使うべきではないでしょうか。それはあなたのコードを短く、より明確にします。 – svick

+0

svickと同意します:pplはあなたの友人です。 –

答えて

5

[注:私は、簡潔にするためのコードと、エラーメッセージから、ほとんどの名前空間の資格を省略している。]

は、Visual Studioのエラー一覧ペインには、各エラーの最初の行を(これは、特に非常に便利な機能であることを示しています。コンパイラからのいくつかのエラーメッセージが非常に長いので、あなたは、エラーメッセージの残りの部分を見るために[出力]ウィンドウを見る必要があり、C++でプログラミングする場合:

error C2664: 'IAsyncOperation<TResult>::Completed::set' : 
cannot convert parameter 1 
    from 'AsyncOperationCompletedHandler<TResult> ^' 
    to 'AsyncOperationCompletedHandler<TResult> ^' 
with 
[ 
    TResult=IVectorView<StorageFile ^>^
] 
and 
[ 
    TResult=IVectorView<IStorageFile ^>^
] 
and 
[ 
    TResult=IVectorView<StorageFile ^>^
] 
No user-defined-conversion operator available, or 
Types pointed to are unrelated; 
conversion requires reinterpret_cast, C-style cast or function-style cast 

これはまだ、すべての3つのテンプレートので、少し混乱していますパラメータTResultを使用します。エラーを解読するには、順序o最初の行のテンプレートは、残りの行のテンプレート引数リストの順序と一致します。

ここで問題となるのは、混合使用率がStorageFileIStorageFileであることです。これらの行の両方で、あなたは(IStorageFileが使用されている場所のためのラインの下にニンジンを参照)StorageFileを使用する必要があります。

getResourceFiles->Completed = ref new Windows::Foundation::AsyncOperationCompletedHandler< IVectorView<Windows::Storage::IStorageFile^>^ >( 
                                 ^
[this](Windows::Foundation::IAsyncOperation< IVectorView<Windows::Storage::IStorageFile^>^ >^ operation) { 
                      ^

注意あなたがこの問題を修正後、あなたのラムダが必要なので、あなたがエラーの別のペアを買ってあげること2つのパラメータを持つ。 2番目はAsyncStatusです。最後に、彼らは両方のように宣言する必要があります。私は、WinRTのために構築していますので

// Namespaces omitted for brevity 
[this](IAsyncOperation<StorageFolder^>^ operation, AsyncStatus status) { } 

、私は非常に便利なFindFirstFileFindNextFile機能を使用することはできません。

実際には、FindFirstFileExFindNextFileの両方をMetroスタイルアプリで使用できます。 (非ExFindFirstFileは使用できません)。

非同期WinRT関数は、可能な限りどこでも実用的ですが、これらの他の関数ではまだ使用されていないわけではありません。

+0

なぜ 'operation'と' status'の両方を持っていますか? 'operation-> Status'は' status'と同じですか? – Zingam

4

もっと簡単な解決策は、非同期操作にPPLを使用することです。代わりに、手動で非同期操作を転がり、試してみてください。

create_task(installedLocation->GetFolderFromPathAsync(folderPath) 
.then([this](Windows::Storage::StorageFolder^ folder) { 
    return folder->GetFilesAsync(); 
}) 
.then([this](IVectorView<Windows::Storage::StorageFile^ >^ files) { 
    for(unsigned int i = 0; i < files->Size; ++i) { 
     // Process File 
    } 
}); 

私はこれはSOコードエディタで書かれた、構文上100%ではないんだけど、それはPPLが劇的にこの種のコードの複雑さを軽減する方法を示しています - 基本的にはcreate_taskを使用してタスクを作成し、タスクの.thenメソッドを使用して、非同期完了に使用されるラムダを指定します。

EDIT:ネストされたラムダを削除するように更新されました。

+0

私はこの構造が好きです。先端に感謝します。 – Jeff

+1

私はちょうどPPL専門家(私の隣のオフィス内)と話しましたが、これにはより良いフォームがあります。これを反映するために私の答えを更新しました。 –

+0

素晴らしいです、これはすばらしく見えます。再度、感謝します。あまりにも私は複数の答えを受け入れることができない悪い... – Jeff

関連する問題