Windows ストア

C# 開発者のための Windows ストア C++: 基本分野を理解する

Bill Kratochvil

コード サンプルのダウンロード

C# の開発者は、パフォーマンスよりも生産性を重視し、多くの機能を備えた開発環境を利用しています。こう発言すると、C# の開発者からは「パフォーマンスには問題はなく、ほとんどの場合、目標を達成するのに必要な水準は超えている」とお叱りを受けるかもしれません。C# の開発者は、最新の C++ に新たな機能強化が施されているとしても、生産性が低下するおそれがあるため、新しい C++ を導入しても投資効果は得られないと考えているのかもしれません。しかし、Windows ストア アプリ開発が優れている点は、再利用可能なコンポーネントをビルドするアジャイル アプローチを利用できることです。このアプローチにより、生産性が向上し、両言語の長所を最大限に引き出して、最も有効なところに C++ コンポーネントを段階的に利用できます。

今回は、最新の C++、C++/CX (コンポーネント拡張機能)、および Windows ランタイム C++ テンプレート ライブラリ (WRL) によって提供される能力やパフォーマンスを利用することを考えている C# の開発者が対象です (最新の C++、C++/CX、WRL をまとめて簡潔に C++ と呼びます)。また、私のように Windows Azure クラウドの能力を活用することを計画している開発者も対象です。C++ でビルドされたアプリは、タブレットや携帯電話のバッテリを長持ちさせる可能性があるだけでなく、ワットあたり、トランジスタあたり、サイクルあたりといった細かいパフォーマンスが向上することでコストが下がる可能性もあります (「C++ および 2011 以降: Herb Sutter – なぜ C++ なのか」bit.ly/1gtKQya、英語)。

C# の開発者が C++ を学習しようとして問題になるのは、ブログなどの利用可能な資料の多くが経験豊富な C++ 開発者の視点から執筆されており、(一般には単一プロジェクトのコンソール アプリをビルドすることのない) C# の開発者の立場を考えていないことです。さらに面倒なことに、C++ では資料の書き換えが進められており、現在の資料の多くが利用されなくなる可能性があるため、新しく効率の良いコーディング テクニックを採用したり注目する気になりません。何が有効で何が有効でないかを判断するには、C++、C++/CLI、C++/CX、WRL、STL、ATL、WinRT といった略語で示される分野の基礎を理解しておく必要があります。基礎がわからないと、C++ で Windows ストア アプリをすぐにビルドできるようになるという本来の目的に適さない資料に時間をかけ、貴重な学習時間を無駄にすることになります。

筆者が C++ に興味を持つようになったのは、複雑なアルゴリズムで 200,000 件以上のレコードを処理しなければならないユース ケースで C# のパフォーマンスが頭打ちになったときです。このとき、Web キャストの「C++ AMP を使用して GPU コンピューティングを管理する」(bit.ly/1dajKE6、英語) にあるデモ アプリを見てパフォーマンスに対する考え方が大きく変わりました。C++ AMP の経験があり、チームにプレゼンテーションを行うために概念実証を作成できるだけの下地があったので、11 秒かかる処理が数ミリ秒に短縮されるところを見せればチームは C++ コンポーネントを快く受け入れるだろうと考えました。残念なことに、利用できる C++ の情報は大量で、中には役に立たない情報もあることに加え、C++ の各分野の知識が不足していたことから、Windows ストア アプリ向けの C++ 開発に関連する情報を探そうとして、膨大な量の情報を前に途方にくれてしまいました。

今回の目的は、C++ について説明するのではなく、情報源を示すことです。これによって学習の道筋が明らかになり、実際に学習を妨げたり無駄にストレスになる膨大な情報によって集中が途切れることなく、スムーズに学習できるようになると考えています。この記事を読み終えたら、C++ 開発に関する最新の MSDN マガジンの記事、ライブラリ、およびブログといった適切な C++ 資料から有益な情報を引き出せるようになるでしょう。

付属のコード ダウンロードは、C#、C++、および JavaScript という異なる開発プラットフォームに基づく 3 つのアプリを含む Visual Studio ソリューションです。このソリューションでは Windows ストア アプリを Wsa と略したプロジェクト名を使用していますが、これは正式な略称ではありません。WsaJavaScript アプリは、MSDN のチュートリアル「チュートリアル: WRL を使用した基本的な Windows ランタイム コンポーネントの作成」(bit.ly/1n1gvV2、英語) を基にしています。付属のアプリでは、このチュートリアル アプリに "Data Binding" と "Data Binding (Reused)" という 2 つのボタンを追加しただけです (図 1 参照)。このソリューションの WsaXamlCpp (C++/CX) アプリと WsaXamlCs (C#) アプリはどちらも同じライブラリを使用し、まったく同じ結果を出力します。

Three Application Views図 1 3 つのアプリ ビュー (アプリは緑、ライブラリは紫、ユース ケースはグレーで示している)

この C# アプリと C++/CX アプリは、Windows ストア アプリの開発が実際のところいかに強力かを示しています。つまり、プラットフォームが変わってもシームレスにコンポーネントを再利用できます (図 1 の右側のペインを参照)。たとえば、コードをレビューしてみると、C# のデモ アプリと C++/CX のデモ アプリはどちらも同じ XML を使用しているのがわかります。アプリのそれぞれのビュー (DataBindingView) に同じ XAML をコピーして貼り付けただけです。同様に、同じプレゼンター (DataBindingPresenter)、ビュー モデル (MainViewModel)、データ アクセス層 (MockDataDal)、およびロガー (DebugLogger) を使用しています。Windows ストア アプリの開発では、C# ライブラリまたは C++ ライブラリをどちらの言語でも作成できるので、C++ の開発を自分のペースで始められ、生産性の低下を最小限に抑えて、それほど効率的でない C# アルゴリズムをパフォーマンスの高い C++ AMP コードに置き換えることができます。

役に立つコードはすべて再利用できるため、生産性が向上します。たとえば、どちらのアプリのロガー (図 2 下部の出力ウィンドウ参照) も C# のコンポーネントで、C# WsaWrcCs プロジェクトに含めています。C++ のロガーをビルドしてもパフォーマンスへの効果は無視できる程度なので、このビルドに時間をかけるよりも、より重要な分野に集中します。図 2 では、C# コードと C++/CX コードの DataBindingPresenter クラスにはほとんど違いがないこともわかります。このクラスにアプリの大部分のコードを含め、他のロジックは共有コンポーネントに含めています (どちらのアプリ プロジェクトにもほとんどコードが含まれていません)。

C++/CX and C# Code Using the Same View Model, Data Access Layer and Logger図 2 同じビュー モデル、データ アクセス層、およびロガーを使用する C++/CX と C# のコード

ここで示すソリューションは、Windows ストア アプリの開発能力を示すこと以外に、C++ の開発に着手できるサンドボックスを提供します。大半のチュートリアルやサンプルは、Windows ストア アプリ環境ではほとんど意味がないコンソール アプリのコードが示されています。それに対して、今回のソリューションでは実際に関心があるプロジェクトの種類 (最新の C++、WRL、または C++/CX) に当てはめることができるサンプル コードを提供しています。このサンプルでは、どのようにすれば C# アプリから C++ コードに簡単にアクセスできるかがわかります。

ここからは、Windows ストア アプリの開発に当てはめることができる C++ の各分野のトピックを取り上げていきますが、各分野についてはそれほど詳しく説明しません。ただし、調査を続けられるだけのベースラインは提供し、必要に応じて詳細を確認できるようにリンクをいくつか用意します。今回の課題のポイントは、あまり当てはまらない膨大な情報を効率良く取り除き、理解すべき重要なトピックに注目できるように支援することです。今回は、Microsoft C++ 開発チームの助力により、膨大な情報ライブラリの中から Microsoft C++ 開発者になるために必要な情報を効率良く見つけることができました。

Windows ランタイム (WinRT)

WinRT 型システムにより、さまざまな言語を使用して (WinRT の型として公開される) Windows API にアクセスでき、アプリやコンポーネントを同じテクノロジを使用して作成できるようになります。WinRT はアプリケーション バイナリ インターフェイス (ABI) に基づきます。ABI は API と同様、コンポーネントを接続するための標準です。

図 1 で示したように、さまざまな開発プラットフォームがシームレスに統合されます。JavaScript、C#、および C++ を使って開発した Windows ストア アプリでは、開発者が意識しなくても C#、C++、および C++/CX が使用されます。これを可能にするには、コンパイル済みのコードを使用できるように、すべての開発言語が準拠する標準インターフェイスを用意する必要があります。これを実現するには、WRL および WinRT コンポーネントの各プロジェクトでクロス言語ヘッダー ファイルとして機能する .winmd ファイルを生成します。.winmd ファイルは実質的には CLI メタデータ ファイルです (そのため、ILSpy で表示できます)。

C++/CX、WRL、C#、および JavaScript (または WinRT ABI のサポートを追加する他の言語) を使用して、ABI を作成および利用します。C# の開発者は日頃使い慣れているものに近い C++/CX を使ってすべてのコードを記述してしまいがちですが、WinRT の使用はできる限り最小限に抑え、ABI 層での使用に厳しく限定します。たとえば、ABI 層に限定できないときは、コードでは C++/CX だけを使用して C++ の能力を活かすようにします。言語の設計と目的から、C++/CX にはそのコンポーネントを対象とする関数の小さなサブセットしか含まれていません。つまり、スタンドアロンの開発言語にすることは意図されてなかったため、使い慣れていて必要になることが多いほとんどの関数に String がありません。ABI とその制約を理解すれば、C++/CX の開発に役立ちます。このトピックについては、「メトロスタイル アプリ向け C++ の詳細」(bit.ly/1k7CWLq、英語) といった Channel 9 のビデオの視聴がお勧めです。

ライブラリ

C++ のユーザーにとっては、標準テンプレート ライブラリ (STL) が最も重要なライブラリです。テンプレートとジェネリックはどちらも「タイプ セーフなジェネリック コンテナーをどのようにして作成するか」という疑問の答えです。C++ のテンプレートと C# のジェネリックの構文は、ある程度似ていますが考え方はかなり異なります。テンプレートはコンパイル時を対象としていますが、ジェネリックは実行時を対象としています。C++/CLI について言えば、キーワードと構文が異なることから大きく異なります。C# の観点からは、ジェネリックと同様にテンプレートを扱えば、ある程度なじみあるものだとわかります。

MSDN ライブラリのドキュメント (bit.ly/1bZzkTB、英語) で示されているように、STL は、STL のアルゴリズムまたは開発者が定義する他の関数によって、STL コンテナーまたは開発者が定義するその他のシーケンスに反復子を適用するための統一標準を確立します。これが STL の共通定義なので、当然、STL のアルゴリズム、反復子、コンテナーを理解する必要があることになります。ここでは詳しく取り上げませんが、MSDN ライブラリには適切なドキュメントが掲載されています。

C++ STL は、C++ の標準ライブラリとは違います。MSDN ライブラリのドキュメントによると、Visual Studio 2013 の標準 C++ ライブラリは、C++ プログラムから呼び出すことができる多くの関数の標準実装です。これらの関数は、入出力などの不可欠なサービスを実行し、頻繁に使用される操作の効率的な実装を提供します (bit.ly/1eQkPlS、英語)。

アクティブ テンプレート ライブラリ (ATL) は、小さく高速の COM オブジェクトを作成できるようにするテンプレート ベースの一連の C++ クラスです。ATL は、ストック実装、デュアル インターフェイス、標準 COM 列挙子インターフェイス、接続ポイント、ティアオフ インターフェイス、ActiveX コントロールなど、重要な COM 機能向けの特殊なサポートを含みます (bit.ly/1engnjy、英語)。WinRT アプリでサポートされるのは、COM および WINAPI の小さなサブセットだけです。WinRT アプリには、WRL の方が適しています。

WRL は WinRT 用に単純化された ATL のようなものです。WRL は、C++ の標準機能を使用して WinRT クラスを開発するのに役立つ一連のヘッダーとテンプレートから構成されます。WRL は、WRL がなければ追加する必要がある膨大な量の定型コードを取り除き、ほぼ同様の機能に C++/CX で必要になる行数を削減します。大半の開発者が WinRT コンポーネントを作成および利用するための手段として想定するのは C++/CX です。ただし、例外を禁止したり他の特殊なニーズを持つコード ベースで WinRT コンポーネントを作成および利用する必要がある場合や、必須でない限りは専用の言語拡張機能の使用を単に控えたい場合は除きます。WRL は、Windows ストア アプリと対話操作するための最も低レベルの C++ 開発です。WRL には XAML コンポーネントをビルドする機能がいくつか不足しているため、C++/CX または C# だけを使用して XAML コンポーネントを作成することになります。

C++

最新の C++ (バージョン 11 以上) は以前のバージョンと大きく異なり、現在多くの書籍、ブログ、記事に掲載されている情報は古くなっているので注意が必要です。"new" や "delete" に言及している資料は旧バージョンの C++ が対象です。ただし、掲載されている古い情報が機能しなくったり、役に立たなくなったわけではありません。C++11 は既存のコードでも適切に動作するため、コードを書き直す必要はありませんが、単純に最新 C++ の簡潔性や効率性は利用できなくなります。

C++/CX は、WinRT 型を作成するのに C# の開発者にとっては比較的わかりやすい方法です。この言語拡張機能は、WinRT 型の作成および利用を容易にすることを目的として作成されましたが、これを使わなければならないわけではありません。実際、WRL でも同じことを実現できますが、WRL の場合は容易でも直接的でもありません。C++/CX は C++/CLI の構文を取り入れていますが、異なるランタイムを対象にしています。

一般に、C++/CLI は Windows デスクトップ開発では使用されません。通常、かなり限られた状況下のマネージ コード向けに限定して使用されます。たとえば、あるタスクを適切に実行する既存のネイティブ コードがあり、これを公開して簡単にマネージ コードから使用できるようにしますが、マネージ コードに公開するインターフェイスが COM または P/Invoke を経由では完全には公開されないような場合です。C++/CLI が対象とする開発者はごく少数です。ここで C++/CLI を取り上げたのは、^ (ハット) 表記に類似点があることや、一部の CLI コード サンプルは C++/CX と互換性がないので混乱を招くおそれがあるためです。

C++/CLI アプリと C++/CX を使用して記述した Windows ストア アプリはどちらもハット表記を使用します。C++/CX を使用した (Windows ストア アプリではない) Windows デスクトップ アプリでは WinRT コンポーネントを使用できます。この場合にハット表記を使用します。C++ を使用した Windows ストア アプリと Windows デスクトップ アプリはどちらも WinRT コンポーネントを使用できます。この場合はハット表記を使用しません。

インターネットを調べるときは、検索語句の先頭に "最新の C++" または "C++/CX" を付けて、適切なドキュメントを参照することをお勧めします。

歴史の教訓

以前、ソフトウェアの再利用と言えば、必ずしもコードにアクセスしなくても、コンポーネントにアクセスできるようにすることを意味していました。これは、スタティック リンク ライブラリ (.lib) ファイルとヘッダー (.h) ファイルを用意することで実現できました。他の開発者は .lib をさまざまなアプリにリンクすることができます。ここでヘッダーはインターフェイスを提供し、ライブラリはコンパイル済みのコードを提供します。

この手法特有の問題の 1 つは、使用するメモリとディスク領域の量です。たとえば、6 つのアプリからなるソフトウェア製品の各アプリに 2MB のライブラリをリンクしてコンパイルすると、占有するディスク領域は 12MB になります。当然のことですが、当時の XT 互換の平均的な PC のディスク領域は 20MB でした。その後、DLL の登場で、1 つのコード セットを複数のアプリが共有できるようになりました。同じライブラリを DLL にすると、先ほどの 6 つのアプリは 2MB しか占有しなくなります。

ここでは、スタティック ライブラリと DLL を比較した場合の長所と短所を詳しく取り上げることはしません。MSDN ライブラリのドキュメントに、両ライブラリに関する包括的な参考資料があります。

スタティック ライブラリと DLL は、最新 C++ ライブラリのビルドにも利用されます。ただし、JavaScript、C++、および C# による Windows ストア アプリから簡単にアクセスできる再利用可能なコンポーネントをビルドしている場合、(C# の開発者が使い慣れている) Windows ストア アプリの DLL を反射的に選択しないようにしてください。後ほど説明しますが、Windows ストア アプリの DLL はこれまでの DLL とは異なります。代わりに、WinRT コンポーネント (以下 WRC) 用のプロジェクト テンプレートを選択します。WRC はマイクロソフトが推奨するコンポーネントで、これまでと最も近い開発エクスペリエンスを実現します。

プロジェクト テンプレート

C# の開発者にとっては、新しいライブラリを追加するのは簡単なことです。クラス ライブラリ プロジェクトを追加し、インターフェイス、クラスなどをビルドします。クラス ライブラリを参照するには、アプリのクラス ライブラリ プロジェクトまたは他のクラス ライブラリへの参照を追加するだけです (生産性が最も高くなります)。

残念ながら、C++ ライブラリのビルドはそれほど簡単ではなく、本稿執筆時点では、再利用可能なコンポーネントを開発するために Visual Studio をセットアップする方法 (具体的には、さまざまな利用可能なプロジェクト テンプレート型を構成する方法) に関するドキュメントはあまり見つかりません。ここでは、Visual Studio をセットアップして、Windows ストア アプリの C++ プロジェクト テンプレートを使用する際に役立つ情報を示します。

WinRT コンポーネント

"DLL (C++/CX)" に関する MSDN ライブラリのドキュメントでは、Windows ストア アプリ用に DLL を作成する必要があるときは、その名前のプロジェクト テンプレートを使用することで、DLL を WinRT コンポーネントとして作成するよう示されています (http://msdn.microsoft.com/ja-jp/library/windows/apps/hh699881.aspx)。前述のように、このオプションにより、最も使い慣れたエクスペリエンスでライブラリを追加および参照できます。

図 2 で示したように、C++/CX と C# には多くの類似点があるため、C# の開発者はすぐに C++ に取り組むことができます。WinRT コンポーネントの興味深い点は、C# と C++ の Windows ストア アプリでは特に意識することなく WinRT コンポーネントを使用でき、C# の開発者は、状況に応じて生産性とパフォーマンスの両方に注力できます。したがって、前述のように、既存の C# ロガー コンポーネントを C++ XAML Windows ストア アプリで再利用する場合は、コードを C# WRC プロジェクトに移植するだけです。サンプル ソリューションで行ったように、C++ アプリと C# アプリのどちらからでも既存の C# ロガー コンポーネントを参照できるようになります。

ABI では、クラスをシールする必要があるといった制約がいくつか課されるため、「抽象化よりも複合」を重視する新たな視点で開発を考える必要があります。この考え方は、複合アプリのビルドにかなり役立ちます。

WRL クラス ライブラリ プロジェクト テンプレート

WRL クラス ライブラリ プロジェクト テンプレートは、WRL を使用してビルドされた一連のユーザー定義クラスです。残念ながら、WRL のチュートリアルや説明はかなり複雑になります。WRL の概要や WRL クラス ライブラリ プロジェクト テンプレートの理解に役立つ資料として、チュートリアル「チュートリアル: WRL を使用した基本的な Windows ランタイム コンポーネントの作成」(bit.ly/1n1gvV2、英語) をお勧めします。ライブラリへの参照を単純に追加するだけで、ほんの数行のコードで JavaScript アプリから C++ コードにアクセスできるようになります。このチュートリアルは、今回提供するサンプル ソリューションの基礎となったものです。

このチュートリアルには、WRL クラス ライブラリ テンプレートを使用して WRL プロジェクトを生成する際に参考になる重要なリンクも提供しているため、WRL 初心者には貴重な資料です。このテンプレートには、IDL ファイルを処理する MIDL コンパイラーを呼び出すために必要な情報が含まれています。詳細については bit.ly/1fLMurc (英語) を参照してください。背後では、MIDL コンパイラが、WRL 開発に関連するすべてのオーバーヘッドを処理する Contoso WRL プロジェクトに必要な (隠し) ファイル (contoso_h.h、contoso_i.c、および contoso_p.c) を生成します。チュートリアルにも記載されていますが、作成する必要があるのは contoso.idl ファイルと contoso.cpp ファイルだけです (図 3 および 図 4 にこの 2 つを示します)。今回は、チュートリアルには含まれていなかった、AddStr(string, string) 機能を追加しました。

図 3 Contoso.idl

 

import "inspectable.idl";
import "Windows.Foundation.idl";
import "ocidl.idl";
#define COMPONENT_VERSION 1.0
namespace Contoso {
  interface ICalculator;
  runtimeclass Calculator;
  [uuid(0be9429f-2c7a-40e8-bb0a-85bcb1749367), 
    version(COMPONENT_VERSION),
    exclusiveto(Calculator)]
  interface ICalculator : IInspectable
  {
    // msdn.microsoft.com/library/jj155856
    // Walkthrough: Creating a Basic Windows Runtime Component Using WRL
    HRESULT Add([in] int a, [in] int b, [out, retval] int* value);
    HRESULT AddStr([in] HSTRING a, [in] 
    HSTRING b, [out, retval] int* value);
  }
  [version(COMPONENT_VERSION), activatable(COMPONENT_VERSION)]
  runtimeclass Calculator
  {
    [default] interface ICalculator;
  }
}

図 4 Contoso.cpp

#include "pch.h"
#include "Contoso_h.h"
#include <wrl.h>
#include <string>
#include <memory>
#include "Calculator.h"
using namespace std;
using namespace Microsoft::WRL;
using namespace Windows::Foundation;
namespace ABI {
  namespace Contoso   {
    class Calculator : public RuntimeClass<ICalculator> {
      InspectableClass(RuntimeClass_Contoso_Calculator, BaseTrust)
    public:
      // Use an external C++ Windows Store App DLL to handle strings
      // note: WRL doesn't permit overloading functions
      HRESULT __stdcall AddStr(_In_ HSTRING a, _In_ HSTRING b, _Out_ int* value)
      {
        // Convert HSTRING values into const wchar_t*
        // so you can pass them into C++ DLL
        const wchar_t* buffera = WindowsGetStringRawBuffer(a, nullptr);
        const wchar_t* bufferb = WindowsGetStringRawBuffer(b, nullptr);
        // Instantiate calculator using modern methods – reference        
        // msdn.microsoft.com/library/hh279669
        auto calc = make_shared<WsaDllCpp::Calculator>();
        // Add the string values
        auto val = calc->Add(buffera, bufferb);
        // Assign value
        *value = val;
        return S_OK;
      }
      // msdn.microsoft.com/library/jj155856
      // Walkthrough: Creating a Basic Windows Runtime Component Using WRL
      HRESULT __stdcall Add(_In_ int a, _In_ int b, _Out_ int* value)   {
        if (value == nullptr)
        {
          return E_POINTER;
        }
        *value = a + b;
        return S_OK;
            }
      };
      ActivatableClass(Calculator);
  }
}

C# クラス ライブラリと同様、外部プロジェクトまたは外部アプリの WRL コンポーネントを使用するには、このプロジェクトに参照を追加するだけです。

スタティック ライブラリ

最新のツールを使用してプロジェクトごとにコードをリビルドし、コードへの呼び出しオーバーヘッドを最小限に抑える場合は、スタティック ライブラリが適しています。スタティック ライブラリは、異なる時点でビルドされた複数のプロジェクトにまったく同じバイナリを使用したくない場合の選択肢です。

コンパイル済みのコードをアプリにリンクできるように、スタティック ライブラリ (.lib) と関連ヘッダー (.h) の場所をコンパイラが把握する必要があります。そのためには、ソリューションを右クリックし、[共通プロパティ]、[プロジェクト依存関係] を順にクリック後、プロジェクト一覧からプロジェクト WsaWrcCpp を選択し、依存先として .lib ファイル (WsaLibCpp) のチェックボックスをオンにします。次に、プロジェクト WsaWrcCpp を右クリックし、[プロパティ]、[共通プロパティ]、[参照設定]、[新しい参照の追加]、[ソリューション]、[プロジェクト] を順にクリックして、.lib ファイル (WsaLibCpp) を選択します。

ここで、.lib プロジェクトのヘッダー ファイルの場所をプロジェクトが把握できるようにする必要があります。サンプル ソリューションを実行している場合は、WsaWrcCpp (WRC) プロジェクトを右クリックし、[プロパティ]、[構成プロパティ]、[C/C++]、[全般] を順にクリックして、[追加のインクルード ディレクトリ] に .lib プロジェクトのヘッダー ファイルの場所を指定します (サンプルの場合は $(SolutionDir)WsaLibCpp;<既存のパス> になります)。

DLL

ダウンロード可能なサンプル ソリューションには、WsaDllCpp という C++ プロジェクト用の Windows ストア アプリ DLL があります (図 2 参照)。このサンプルは、MSDN ライブラリの記事「チュートリアル: ダイナミック リンク ライブラリの作成と使用 (C++)」(bit.ly/1enxzWc、英語) を参考にしました。(Microsoft C++ の開発者やレビューアによると) このプロジェクトはデモのみを目的としているため、この DLL を実際に使用することはお勧めしません。DLL の説明をここに含めたのは、Windows ストア アプリで既存の DLL を使用する必要が生じることがあるためです。

WsaDllCpp DLL では、2 つの文字列を加算する機能を備えたソリューション Contoso WRL (前述の WRL クラス ライブラリ テンプレート) を利用します。たとえば、WsaDllCpp::Calculator::Add("1000","2000") は 3000 を生成します。次のインターフェイス コードは C# の DLL と C++ の DLL の違いを示しています。

 

#pragma once
#include <string>
#define WSADLLCPP_API __declspec(dllexport)
namespace WsaDllCpp
{
  class Calculator
  {
  public:
    WSADLLCPP_API int Add(const wchar_t* numberOne, 
      const wchar_t* numberTwo);
    WSADLLCPP_API int Add(int numberOne, int numberTwo);
  };
}

ご覧のとおり、関数を外部ライブラリや外部アプリに公開するためのオーバーヘッド (__declspec) が若干あります。同様に、WsaDllCpp をアプリに正しくコンパイルするために必要な設定は、プロジェクト参照を設定するだけではすみません。Contoso WRL プロジェクトを右クリックし、[プロパティ]、[構成プロパティ]、[C/C++]、[全般] を順にクリックして、[追加のインクルード ディレクトリ] に .lib プロジェクトのヘッダー ファイルの場所を指定する必要があります。

C# の開発者にとっては、DLL への参照を追加するのは直感的ではありません。少なくともいつもの操作とは異なります。通常は、右クリックする "参照" リンクがプロジェクト一覧にあります (これは WRC プロジェクトで見つかります)。.lib ファイルと同様、参照を追加するには、プロジェクトを右クリックし、[追加] および [参照] をクリックしてから、[新しい参照の追加] をクリックします。

C# の開発者と違って、選択したパスが相対パスに変換されるとは想定できません。そのため、Visual Studio マクロを使用してパスを指定するようにしてください。前述の例では、[追加のインクルード ディレクトリ] に $(SolutionDir)WsaDllCpp; <既存のパス> を指定する必要があります。

まとめ

情報源を絞り込んだら、多くの情報 (特に MSDN ライブラリの情報) を参考にして、学習プロセスを効率的かつ実りあるものにしてください。C++ の各分野の基礎を理解する今回のステップは、C++ の Windows ストア アプリの調査や開発に役立ちます。不適切な情報 (以前の C++、MFC、C++/CLI、およびほとんどの ATL に関する情報) は限られているので、このような情報に注意すれば、無駄な資料を読むことに貴重な学習時間を割く必要がなくなります。

Kenny Kerr の MSDN マガジンの記事 (bit.ly/1iv7mUQ、英語)、Channel 9 (bit.ly/1dFqYjV、英語)、および Michael B. Mclaughlin の記事 (bit.ly/1b5CDhs、英語) を参考にすることもお勧めします。このサイトに記載されていない Michael B. Mclaughlin の貴重な情報源として、「C# から C++ - 入門ガイド」(bit.ly/MvdZv4、英語) もあります。

C++/CX、最新の C++、および WinRT コンポーネントの使用に注目すれば、Windows ストア アプリ開発環境での目標を実現することができます。

Bill Kratochvil は、テキサス州アマリロに拠点を置き、ソフトウェアの設計および開発を請け負う Global Webnet LLC のオーナーです。現在、彼は医療業界の大手企業と契約を結んでいます。

この記事のレビューに協力してくれた、マイクロソフト技術スタッフの Mohammad Al-Sabt、John Cuyle、Chris Guzak、Frantisek Kaduk、Ben Kuhn、および Thomas Petchel に心より感謝いたします。また、Steven Southwick にも感謝いたします。
John Cuyle は、Microsoft Studios の Studios Publishing グループのソフトウェア開発者です。C++ を使用するゲームの開発に 10 年以上の経験があり、さらにそれよりも数年長くゲーム プレーの経験があります。
Ben Kuhn は、Microsoft の開発者として 11 年間勤務し、印刷、クリップボード、Windows ランタイムまで、さまざまなテクノロジに携わっています。最近では、Windows ランタイム用の C++ 言語拡張機能の設計に貢献し、Windows 8.1 サンプル パックの作成を支援しました。
Thomas Petchel は、Visual C++ 向けシニア コンテンツ パブリッシング マネージャーで、8 年間チームに在籍しています。彼が C++ を好むのは、みなさんと同じように、C++ の能力、パフォーマンス、制御、および思想を理由としています。
Frantisek Kaduk は、.NET の経験が 10 年以上ある、マイクロソフト/スカイプ チームのシニア ソフトウェア開発エンジニアです。また、Skype for Windows 8.x アプリを開発したチームのメンバーでもありました。彼は、たまにブログを更新しています (http://blogs.msdn.com/b/fkaduk、英語)。
Steven Southwick は、主に、モンテ カルロ シミュレーションと分析手法を両方使用する臨床試験登録モデルに力を注いでいる .NET 開発者です。