2016年7月9日土曜日

Visual C++ CoroutineとBoost Coroutine

以前にBoost.Asioを使ってみたんですが、その時は非同期機能を使っていませんでした。非同期機能の場合、完了のコールバックを処理する必要がありますが、そのコーディングはどうしても煩雑になってしまいます。
この点に関してC#言語ではVS2013でasync機能によるサポートが行われるようになりました。この機能は非同期呼び出し時のコンテキストをコンパイラーが保持しておき、完了コールバック時にコンテキストを復元することで一続きの関数のように処理するものです。この機能は一般的にはCoroutine; コルーチンと呼ばれるようです。

実はC++言語でもコルーチンを標準に導入するべく検討がされているらしく、VS2015からサポートされています。VS2015 Update1からはプラットフォームを選ばず機能提供されています。それとは別にBoostライブラリでもBoost.Coroutineによるコルーチンが提供されています。こちらはコンパイラー側のサポートなしにアセンブラでスタックを強引に書き換えることで実現されているらしいです(詳しくはわかりません)。その影響でWindowsプラットフォームではBoost.Coroutineを使うためには/SAFESEH:NOオプションを付け安全な例外ハンドラーが存在しない旨を宣言する必要があります。

そこで、C++言語ネイティブなコルーチンが提供される環境ではそちらを、提供されない環境ではBoost.Coroutineに切り替え、ソースコードを共通化できるライブラリを用意してみました。


これを使うとcoroutine::result<Result> func(..., coroutine::handler handler)のシグネチャを持つ関数を呼び出すことができます。サンプルはこちら。