WisdomSoft - for your serial experiences.

WinRTとプログラミング言語

Windows ストアアプリケーションは Windows で主要なプログラミング言語である C++ 、C# や VB .NET などに加えて、Web 標準技術である HTML と JavaScript を用いて開発することもできます。WinRT のアーキテクチャを俯瞰しながら、各種のプログラミング言語と WinRT の関係を紹介します。

WinRTの基本構造

Microsoft が公式で対応している Windows ストアアプリケーションの開発環境は、これまでと同じように Visual Studio が中心となります。つまり、Windows ストアアプリケーションを開発する環境は従来の Windws PC 環境と同じデスクトップです。

Windows ストアアプリケーションの開発には、複数のプログラミング言語を選択できます。C++、C#、Visual Basic .NET そして、Web 標準技術である HTML + CSS + JavaScript でアプリケーションを開発できます。

ここまで聞くと Windows ストアアプリケーションの実行基盤となっている WinRT は何なのか疑問に感じるでしょう。C++ で開発できるということは OS に直結したネイティブコードでしょうか。C# で開発できるのだから .NET Framework ベースのマネージコードと考えるのが自然でしょうか。それとも HTML + CSS + JavaScript で開発できるのだから、Chrome OS のようなブラウザエンジンを応用したアプローチかもしれません。

どれも間違いではありませんが Windows Runtime 本体は純粋なネイティブコードです。しかし、古い Win32 API のような関数ライブラリではなく、オブジェクト指向設計の COM オブジェクトとして提供されます。C# や Visual Basic .NET は .NET Framework を通じて WinRT オブジェクトにアクセスします。同様に HTML + CSS + JavaScript ベースのアプリケーションは Internet Explorer のスクリプトエンジンである Chakra を通じて WinRT オブジェトにアクセスします。

加えて、.NET Framework や HTML で開発する Metro スタイルアプリケーションにとっても、WinRT を自然に利用できるように工夫されています。ネイティブの WinRT コンポーネントをランタイム環境でラッピングしただけの(例えば Win32 API と Windows フォームのような)関係ではありません。

これまでのデスクトップアプリケーションを振り返ると、なぜ Windows ストアアプリケーションのために WinRT が誕生したのかが見えてきます。確かに、これまでのアプリケーションも C++ や C# など多様なプログラミング言語で開発できましたが、その間には深い谷があり、互いに分断されていました。

図1 分断されたデスクトップアプリケーション環境
図1 分断されたデスクトップアプリケーション環境

図1は従来のデスクトップアプリケーションを構成するプログラミング言語と API の関係を表しています。例えば C++ によるネイティブアプリケーションであれば Win32 API や DirectX を用いて開発し、C# による .NET Framework アプリケーションであれば Windows フォームや WPF を用いて開発したでしょう。呼び出す API は構造も設計思想も大きく異なり、移行するには開発者が新しいフレームワークを学習しなければなりません。C++ で開発されたネイティブコードと .NET Framework のマネージコードを通信させるには、さらに面倒なコードを書かなければなりません。

WinRT は、このような問題を根本から解決するため、どの言語環境からも共通のコンポーネントを参照します。ランタイム環境ごとに使用するフレームワークが異なるということはありません。どの言語で開発しても、同じ WinRT です。プログラミング言語によって、文字列や配列など型の扱いが異なりますが、WinRT はプログラミング言語に依存しない基本型を持ち、それらは言語プロジェクション(Language Projection)を介して、各プログラミング言語にとって自然な型に置き換えられます。

図2 WinRTアーキテクチャ
図1 WinRTアーキテクチャ

この言語プロジェクションの働きによって、例えば C# 言語で開発する場合でも WinRT で提供される各種コンポーネントが .NET Framework 型のように振る舞います。WinRT がネイティブの COM オブジェクトであることを意識することなく利用できます。言語プロジェクションの存在も、普段の開発では意識する必要なないでしょう。

言語プロジェクションが WinRT コンポーネントを各プログラミング言語の型に接続できるのは Windows メタデータ(Windows Metadata)と呼ばれる型情報に基づきます。Windows メタデータは .NET Framework のアセンブリに含まれるメタデータと互換性があり、この Windows メタデータが提供する情報によって高度な言語間の接続を可能としています。また、Windows メタデータによって提供される型情報があるため、ネイティブである WinRT のライブラリも .NET Framework と同じように、既知の静的な型に対して IntelliSence による入力支援が得られます。

Windows メタデータは winmd という拡張子で、WinRT のメタデータは x64 版 Windows であれば「C:\Windows\SysWOW64\WinMetadata」フォルダ内に配置されています。Windows メタデータは .NET Framework アセンブリのメタデータと基本的に同じ構造のバイナリなので、ildasm.exe (逆アセンブラ―)で中身を見ることも可能です。

図3 Windows メタデータ
図3 Windows メタデータ

例えば C# などで開発する WinRT 用ライブラリで、C++ など他の言語からも利用する場合は .NET Framework アセンブリではなく Windows メタデータを生成します。

重要なのは WinRT そのものは純粋なネイティブのコンポーネントであり、これを .NET Framework や JavaScript など、ランタイム環境やプログラミング言語を超えて自然に取引出るようにするための仕組みとして言語プロジェクションと Windows メタデータという新しい手法が採用されている点です。