Windows ランタイム C++ テンプレート ライブラリ (WRL)
C++/CXでもない、標準のC++からWinRTのAPIが使用できる方法が以下のサイトであったので、いろいろと調べてみました。
(C++/CLIからできないことはテスト済み)
WRL を使用して非同期操作を完了する
http://msdn.microsoft.com/ja-jp/library/vstudio/hh973451.aspx
エラー処理を省略するなどしてソースを見やすくしました。
環境 : VisualStudio 2012 / Windows 8
プロジェクトは、C++ の空のプロジェクトを使い、runtimeobject.libを「追加の依存ファイル」に追加します。
#include <Windows.Foundation.h> #include <Windows.System.Threading.h> #include <wrl/event.h> #include <stdio.h> #include <Objbase.h> using namespace ABI::Windows::Foundation; using namespace ABI::Windows::System::Threading; using namespace Microsoft::WRL; using namespace Microsoft::WRL::Wrappers; int main() { // Initialize the Windows Runtime. RoInitializeWrapper initialize(RO_INIT_MULTITHREADED); // Get the activation factory for the IThreadPoolTimer interface. ComPtr<IThreadPoolTimerStatics> timerFactory; HRESULT hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_System_Threading_ThreadPoolTimer).Get(), &timerFactory); // Create an event that is set after the timer callback completes. We later use this event to wait for the timer to complete. // This event is for demonstration only in a console app. In most apps, you typically don't wait for async operations to complete. Event timerCompleted(CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, WRITE_OWNER | EVENT_ALL_ACCESS)); // Create a timer that prints a message after 2 seconds. TimeSpan delay; delay.Duration = 20000000; // 2 seconds. auto callback = Callback<ITimerElapsedHandler>([&timerCompleted](IThreadPoolTimer* timer) -> HRESULT { TimeSpan delay; HRESULT hr = timer->get_Delay(&delay); if (SUCCEEDED(hr)) { printf("Timer duration: %2.2f seconds.\n", delay.Duration / 10000000.0); } // Set the completion event and return. SetEvent(timerCompleted.Get()); return hr; }); ComPtr<IThreadPoolTimer> timer; hr = timerFactory->CreateTimer(callback.Get(), delay, &timer); printf("Timer started...\n"); // Wait for the timer to complete. WaitForSingleObjectEx(timerCompleted.Get(), INFINITE, FALSE); // All smart pointers and RAII objects go out of scope here. }
cl.exe wrl-consume-asyncOp.cpp runtimeobject.lib
VisualStudioを使わなくても、コンパイルは上のように簡単にできますが、使うプロジェクトとか、ヘッダの中身を確認したかったので、あえて使ってみました。
(たしかに標準C++であるという確認のため)
実行すると以下のようにコンソールに出力します。
Timer started.
Timer duration: 2.00 seconds.
二秒後にコールバックを登録した処理を動作させるものです。WinRTのランタイムでなくてもできることですが、現在は標準C++からでもWinRTのAPIがコールできるという確認にとどめたいと思います。もっとWinRTらしい使い方を見つけたらまたテストしたいと思います。
あと、WRTが低レベル、C++/CXが高レベルという位置づけのようです。
ストアアプリがネイティブコードを出力しているということが少し実感できました。(よりハードに使いところで動作させることは、逆行する動きなのかそれともこれかのトレンドなのか・・)