[win8] C++/CLI と C++/CX の違い

Microsoft 社の公式見解は、何処かにある(?)と思うので、私のほうで Visual Studio 11 beta を1か月程触った感じで言いますと、

  • 「C++/CX って、C++/CLI の後継でも何でもないやんッ!!! まったく別物じゃ」
  • 「C++/CX って、metro アプリケーションは作れるけれど、desktop アプリは作れないじゃんッ!!!」
  • 「C++/CLI って、metro アプリが作れないどころか、WPF アプリも相変わらず作れないじゃんッ!!!」
  • 「C++/CX って、WinRT を扱えるけど、.NET Framework を扱えないじゃん、つーか、C++ の世界に戻らないとだめじゃんッ!!!」
  • 「そもそも、C++/CX と C++/CLI って混在できないじゃんッ!!!」

ってな具合で、憤懣ひとしきりなんですよ。というわけで、ちょっと以下に戯言を。

希望/期待としては、C++/CLI が更に拡張されて XAML を扱えるようになって、なもんだから metro アプリを作れるよ、という流かと思っていたのですが相当違うようです。WinRT に隠されているというか、C++/CLI は爆死状態というか。いえ、おそらく去年の build で分かっていた段階なんでしょうが、ちと去年の夏頃は別件で忙しくてあまり C++/CLI を眺めてはいなかったんですよね~。ベータ版をインストールして、metro の C++ プロジェクトをさくりと作って「ああ、インテリセンスが動く、進化したなぁ」と思っていた訳ですが、いえいえ、あれは「C++/CX」のほうで「C++/CLI」ではなかったのですね。

さて、「C++/CX」と「C++/CLI」という用語が頻発していますが、microsoft さんの講演の中は一律して「C++」として扱っています。と言いますか「C++/CLI」には一切触れずに、「C++/CX」のことを「C++」と称しています。「Visual Basic .NET」のことを「Visual Basic」と言うようになった流れと同じ感じだと思います。

C++/CLI というのは、「.NET Framework の共通言語基盤(ランタイム)を扱えるC++」という意味です。正式名称は「C++ with Common Language Infrastructure」ってところですかね。単体で Windows アプリケーションを作れますが、主な仕事としては、「旧来のC/C++ライブラリを、そのままC#で扱えるようにする」なところで、単体で扱うことは非常に稀です。Windows アプリを作るならば、C#/VB で作ったほうが手早く作れます。ですが、C++ の文法から、.NET Framework をあつかうことができるので、C#/VB と同じようにプログラミングをすることができます。
ただし、欠点としては、

  • Visual Studio 2010 上でインテリセンスが効かないこと。
  • XAML が扱えないので、WPF や Silverlight アプリケーションが作れないこと。

があります。インテリセンスのほうは、Visual Studio 2008 を使えばよいので特に問題はありません。まあ、Visual Studio 2010 では実質開発ができない状態だったので、なんとも言えないところですが。
XAML が扱えないのは今回の visual studio 11、windows 8 で致命的なところです。

一方で、「WinRT が扱える C++」として登場しているのが「C++/CX」です。正式名称は「C++ with Component Extensions」ってことで、WinRT≒DCOM で拡張されている C++ という意味合いです。今回の Visual C++ 11 の売りは、「C++ で metro アプリケーションを作れる」ことです。metro アプリケーションというのは、windows 8 の主流となるタブレット型のアプリケーションで、内部的には XAML を使っています。となると、意訳すれば「XAML を扱える C++」ということになります。

さて、C++/CLI では XAML を扱えない。逆に、C++/CX では XAML を扱える。という区別があります。このために、C++/CLI と C++/CX の開発領域は二分されて、

  • desktop アプリ(従来の windows アプリ)の場合は、C++/CLI
  • metro アプリの場合は、C++/CX

という住み分けができます。文法的はどちらも C++ をベースにして拡張されていしマネージドポインタ「^」や「%」の扱いも同じなのでほぼ互換性があります。主な違いは、「gcnew」と「ref new」の違いぐらいです…で済めばよいのですが、実際コーディングをしてみると大きく違います。

今回、metro アプリケーションを C++ で作れるようにした理由に「ゲームアプリケーション」があります。タブレット市場でもゲームの割合は大きくて、グラフィック機能とマシンパワーを存分に使ったゲームは、windows 8 になると飛躍的に上がる(と思われる)ところです。
さて、私の場合ゲーム開発業界に疎いので正確なことは分からないのですが、察するに windows 7 の頃のゲーム開発の場合は、

  • グラフィックを扱うならば DirectX を使う。
  • 余りパフォーマンスがいらないところは、Microsoft.Xna.Framework

なのだと思います。DirectX はグラフィックボードの機能を存分発揮できるようにと開発されたインターフェースでC/C++で扱います。途中で、DirectX の .NET Framework 版があったのですが、その後 Microsoft.Xna.Framework に吸収されています。
で、ゲームのパフォーマンスを出す上で、.NET Framework が十分対応しているかというと、そうではありません。結局グラフィック関係は、WinRT に残していることを考えると GC を含む virtual machine 環境ではきついものがあります。メモリへの直接アクセスが禁止されていることのデメリットは、OpenCV や Fortran を触るとよく分かります。

このあたり、C++/CLI の出番かと思っていたのですが、ゲーム業界としては、MFCやATLぐらあらばOKで、わざわざ .NET を使う理由は無かったのですね。

で、どういう要望および内部抗争(?)があったのかは知りませんが、metro アプリケーションがタブレット型を主戦場としていることと、タブレット型ではゲームが流行ることを考えると、metro アプリ + DirectX(C/C++) の組み合わせは避けられない。しかし、C++/CLI では XAML が使えない。どういう理由か分からないけども、XAML を扱うように拡張できない(マンパワーがないのか、開発者が抜けてしまったのかはわかりません)。

という訳で、C++/CLI はばっさり切り捨ててしまって、XAML + C++ という組み合わせの新しいプラットフォームを作った訳です。これが「C++/CX」です。
なので、C++/CX の主戦場が、DirectX 廻りやネットワーク廻りなので、そのあたりが WinRT≒DCOM で補ってしまえば、「ひとまずは」.NET Framework はいらないわけです、C++/CLI をゲーム業界の方が使わないのと同じ理由で、metro アプリを作るときにも .NET Framework は要らないでしょう、という想像が働きます。

こういう経緯を考えてみると、先の憤懣の部分にコメントを付けて、

  • 「C++/CX って、C++/CLI の後継でも何でもないやんッ!!! まったく別物じゃ」
  • → もとも発祥は別物。ゲーム関係の必要性からだから。

  • 「C++/CX って、metro アプリケーションは作れるけれど、desktop アプリは作れないじゃんッ!!!」
  • → ゲームなんだから、metro アプリで十分。

    → desktop アプリは従来のインストーラーが必要なので、流行らないと思われる

  • 「C++/CLI って、metro アプリが作れないどころか、WPF アプリも相変わらず作れないじゃんッ!!!」
  • → C++/CLI は、元のままで良いので、WPF アプリを使えなくてもよい。

    → カラフルなUIを必要としないので、XAML を扱えなくてもよい。

  • 「C++/CX って、WinRT を扱えるけど、.NET Framework を扱えないじゃん、つーか、C++ の世界に戻らないとだめじゃんッ!!!」
  • → 多分「間に合わなかった」んじゃないかな?

    → そのうち様子を見て公開するかも。

  • 「そもそも、C++/CX と C++/CLI って混在できないじゃんッ!!!」
  • → C++/CX が .NET Framework を取り込めるようになったら、混在できるようになるかも。

という感じになります。

C++/CX のハマり処は、.NET Framework を使えないところです。もともとゲーム業界で働いている方の場合は、.NET を使わないので、C/C++ の関数/STLの扱いに慣れているので大丈夫だと思うのですが、.NET プログラマが、C++/CX を扱う場合にはハマり処が満載です。

ひとつあげると、C#/VB で良く使われる「String」は、C++/CXの「String」とは全く別物です。.NET の場合は「System.String」なのですが、C++/CX の場合は「Platform::String」なんですね。なので、String::Format メソッドが無くて「えッ!!!」と吃驚します。
ちなみに、C++/CLI の場合は「System::String」なんですよね~。このあたりの話はまた後程。

カテゴリー: C++, windows 8 パーマリンク

[win8] C++/CLI と C++/CX の違い への10件のフィードバック

  1. ピンバック: .NET Clips

  2. las artes のコメント:

    きっと詳しい人からしたら何をやってるんだって噴飯ものなのろうけど教えて。 c#コード側からlistviewを定義するやり方。 xaml難しいよ理解不能なのでコードからやろうとしたらこっちも理解不能だった。 ListViewItem lvi = new ListViewItem(); lvi.Content = new string[] { “test”, “テスト”, “asdf” }; ObservableCollection<ListViewItem> oclvi = new ObservableCollection<ListViewItem>(); oclvi.Add(lvi); あとはoclviをListViewのItemsSourceに突っ込めんでる これビルドできるし動くんだけど、出力ウィンドウに System.Windows.Data Error: 4 : Cannot find source for binding with reference ‘RelativeSource FindAncestor, AncestorType= ‘System.Windows.Controls.ItemsControl’, AncestorLevel=’1”. BindingExpression:Path= HorizontalContentAlignment; DataItem=null; target element is ‘ListViewItem’ (Name=”); target property is ‘HorizontalContentAlignment’ (type ‘HorizontalAlignment’) って出るんだよ。何これ。

    • masuda のコメント:

      どうしたいのか不明なのですが、
      // make data
      var lst = new ObservableCollection();
      lst.Add(“test”);
      lst.Add(“テスト”);
      lst.Add(“asdf”);
      // data bind
      listView1.ItemsSource = lst;
      のように既存の ListView に ItemsSource プロパティを使ってバインドするのでは駄目なのですか?

      # new ListViewItem() としているところの意図がよくわからんのです。

  3. masuda のコメント:

    ちなみに、Visual Studio 11 beta で C++/CLI のインテリンセンスが効きます。beta 版の前は効かなかった気がするので、改善されたなのかなと。まあ、それでも C++/CLI では metro アプリを作れない訳ですが…この違いは面倒臭い。
    と言うか、C# のほうが面倒かもしれませんね。desktop アプリで metro 関係のライブラリが扱えないので、desktop と metro の違いが非常にわかりづらくなるってことで。

  4. Anony のコメント:

    C++/CLIってXamlReader使えばXaml扱えると思いますが、
    C++/CLIでXamlが使えないというのはどういう意味ですか?

    • masuda のコメント:

      端的にいえば、C++/CLI ではWindows ストア アプリを作れないってことですね。
      もともと、C++/CLI には、WPF を作るプロジェクトが VS2010 にないので、このあたりを含めると ≒XAML が扱えないってことです。

  5. Anony のコメント:

    C++/CLIがってよりVisual C++が対応してないって話ですね

    • masuda のコメント:

      詳細を書くとですね、

      C++/CLI with XAML – りもーと・せんしんぐ
      http://d.hatena.ne.jp/signe/20070422
      Visual Studio 11 から本気出す! WPF with C++/CLI
      http://blogs.wankuma.com/episteme/archive/2012/04/28/268916.aspx

      あたりを組み合わせると、外部 xaml を読み込んで、mvvm パターンで c++/cli オンリーで書けそうな気もするのですが、実質ここまで手を書けて c++/cli オンリーで書くメリットは?ってことなんですよ。

      c++/cli only で書くときの条件としては、
      ・内部リソースを使って xaml をロード(これはできそう)
      ・ボタンクリックイベント等を、command パターンではなくて、xaml に click=”” の形でハンドラを設定(こここは不明)
      ・c++/cli の各メソッドを xaml デザイナが読み込めない(たぶん)

      ってことなのですが、かなり手間がかかりそう(VS2012でも、このあたりのサポートはないし)

      ただし、c++/cli を使うメリットとしては、OpenCV を使うとか、Fortran ライブラリを使うとか、GPU 関係を直接扱うとかのメリットは依然としてあるわけで、そのあたり、今後 xaml を使ったインターフェースは、MS さんがどう考えているのかな?という疑問があります。
      どうやら、c++/cx でゲームライブラリとしての direct x を扱う路線は示されているのですが、その他は微妙なんですよね。

  6. Anony のコメント:

    iOSやAndroid、Windowsでソース互換な描画エンジンを稼働させようとしてる私としては、
    有り難そうなんですけどね。尤もQtの方が便利かもしれませんが、iOSの様にハードに併せて画面を取り込み使用するってのはQtを使うより重宝しそうな気がします。

    • masuda のコメント:

      なるほど、iOS/Android/Windows 8 でソース互換ライブラリとなると、C++ 経由のほうがよさそうですね。文法的に Objective-C と C++/CLI の互換は取りやすいかも。

      Qt は使ったことはないのですが、独自のクラスライブラリを構築すると、それぞれのフレームワークのライブラリの良いところが消えてしまうので(最大公約数になるという意味で)、むしろ、MDA っぽくソース互換あるいはアプリケーションツールレベルの互換にとどめておくほうが、開発的には効率的なのかなと、最近は考えていたりします。

コメントは停止中です。