BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース Windows StoreアプリをC++/CXで書く場合の注意

Windows StoreアプリをC++/CXで書く場合の注意

原文(投稿日:2012/10/31)へのリンク

 

C++ /CX と WinRTに深く潜るというタイトルのセッションで Marian Luparu氏は、Windows 8をターゲットにしたC++アプリケーションの例外処理とパフォーマンスについて講演した。開発者が理解すべき最も重要なことは、 いかにWinRTと通常のC++の境界が例外処理とパフォーマンスに効果をもたらすかである。

基本的な例外処理

WinRTは、例外の概念を持っていない、それは内部的にHRESULTを使用している。Platform::Exception から継承したクラスに入れられたデバッグ情報は、ABI境界を超えて移動しない。通常、例外に関連付けらたメッセージは、デバッガのみで利用可能 だ。

もしそれらがABI境界を超えたら、C++ と SEHスタイルの例外は、プロセスを終了させる。すなわち、全てのC++例外は、処理される必要がある。例え、Platform::Exceptionでそれをラップしてもである。

COMException使用を捕捉した際に常にHRESULTを確認すること。もしあるHRESULTを処理する方法がわからない場合は、例外を再スローする。同様に、あなたはCOMメソッドを呼び出して、エラーコードを返す場合、それは直ちに例外になる必要がある。

非同期と例外処理

Parallel Patterns Library (PPL)を使って開発している時、ラムダ式が結果でなくタスクを受け取ることが重要だ。例えば、以下を使う。

.then( [](Task<int> result) {…} )

 

次式ではない。

.then( [](int result) {…} )

 

もし2つ目のバージョンを使い、例外が発生すれば、 “then”ブロックは完全にスキップされる。

非同期とスレッド

C#やVBのasync/await シンタックスのように、PPLはスレッドとなると、難しい。もしUIスレッドで操作を始めたら、それぞれの継続( “then”ブロック)は、またUIスレッド上でスケジュールされる。もしそうでなく、スレッドプールを使いたければ、task_continuation_context::use_arbitraryの結果を “then”メソッドに渡す必要がある。

C++クラスとWinRTクラス

一般的に開発者は、強制されない限り、WinRTスタイルのクラス(refクラス)を使用するべきではない。なぜなら彼らは、XAMLとやり取りしたり、他の言語が使えるようにWinRTコンポーネントを公開するからである。WinRTクラスは、ポータブルでない通常のC++クラスより遅い、すなわち普通のC++アプリケーションでそれらを使うことはできない。

パフォーマンスを改善する別の方法は、WinRT と C++の型の間での変換を減らすことである。WinRT境界を跨いで頻繁に通信すれば、遅くなってしまうだろう。不要なメモリの割当てやデータのコピーは、更に遅くなる。

StringReferenceのような幾つかのラッパークラスは、パフォーマンスの助けになるだろう。しかし注意がいる。 StringReferenceは参照カウントされるので、それがラップするバッファは、 StringReferenceが破棄されるまで変更したり、削除できない。この問題が起きるのは、WinRTが StringReferenceのコピーを手放さない時であるが、これは必ずしも予測できるものではない。 Marian Luparu氏は他の例を上げている。

  1. StringReferenceはバッファをラップするために作成される。
  2. WinRT関数が StringReferenceを使って呼ばれる
  3. WinRT関数がC++コールバックを呼び出す
  4. コールバックが基になるバッファを変更する。
  5. 制御がWinRT関数に戻される。関数は予期せずに変更された文字列を持つことになる。

ArrayReferenceはC++の配列のラッパーとして、同じように使用することができる。しかし、WinRTはC++の配列が不変であることを期待していないので、ひどいことになる可能性は低い。

 

この記事に星をつける

おすすめ度
スタイル

BT