Windows ストアアプリにC/C++ライブラリを組み込む

今更の話題な気もしますが、Windowsストアアプリに既存のC/C++ライブラリを組み込む場合の注意点を説明します。

例えば信号処理や画像処理など、色々なプラットフォームで動くようにANSI Cなどの標準にだけ従って開発されたライブラリがある場合、そのライブラリを組込んだWindows ストアアプリを開発することは可能です。他にも、https://msdn.microsoft.com/library/windows/apps/br205757.aspx で紹介されているWin32/COM APIを使って作られているC/C++ライブラリも組込み可能です。以下、具体的に組込み方法を説明していきます。

UIの部分は、HTML/JS、XAML/C#、XAML/VB、XAML/C++ で開発します。それぞれのアプリ、開発組織に合わせた言語を選択してください。先ずは、Visual Studio 2012で、それぞれ用のストアアプリテンプレートを使ってストアアプリプロジェクトを作成します。そちらはそちらで、アプリのUIをがっつり構築します。

そのプロジェクトが属するソリューションに、VC++→Windows Runtime Componentプロジェクトを作成します。

出来上がったC++プロジェクトのフォルダーに、既存のコード一式をコピー&ペーストします。そして、C++プロジェクトを右クリックして、追加→既存の項目を選択し、既存のコードのソースファイル、ヘッダーファイル、その他必要なリソースファイルなどをプロジェクトに追加してください。追加したライブラリを使うためのラッパーを、VC++のManagedのクラスで作成します。C++プロジェクトを作成したときにできたClass1.h、Class1.cppのクラス名を適切に変更して、使うのが便利です。基本は、

ヘッダーファイル:

namespace WindowsRuntimeComponent1
{
    public ref class Class1 sealed
    {
    public:
        Class1();

        // wrapper method
        int DoWork(int x);
    };

}

というように、名前空間を定義して、refとsealedを指定すれば、JSやC#、Visual Basicから参照可能になります。そして、既存のライブラリの機能をコールするためのメソッド(この例ではint DoWork(int x))を追加します。
例えば、DoWorkメソッド内で、CWork.h, CWork.c で定義&実装されている、int Calculate(int x)という関数をコールしたい場合には、

ソースファイル内で、

#include "CWork.h"
....
int Class1::DoWork(int)
{
    return Calculate(int x);
}

と、ヘッダーファイルをインクルードし、メソッドの中で、既存ライブラリの関数をコールするコードを書いて結び付けていきます。Visual C++の場合は、ManagedとNativeのコードを混在させて書けるので便利ですね。

後は、Windows Runtime Componentのプロジェクトを、UIのプロジェクトの参照に追加(UIプロジェクトを右クリックし、参照の追加でOK)すれば、名前空間をきちんと指定すれば、JSでもC#でもVBでも利用可能になります。例えば、JSの場合は、

var lib = new WindowsRuntimeComponent1.Class1();
var value = lib.DoWork(10);

といった書き方でOK。大抵の場合、組込みたいC/C++ライブラリは、VC++ Managedではないので、追加したファイル群のプロパティの変更が必要です。ちょっと手間ですが、追加したすべての*.c、*.cppファイルについて、ソリューションエクスプローラーで、夫々のファイル毎に、右クリック→プロパティを選択し、

  • C++ → 全般 → Windowsランタイム拡張機能の使用 → "いいえ"に設定
  • C++ → プリコンパイル済みヘッダー →プリコンパイル済みヘッダー → ”プリコンパイル済みヘッダーを使用しない”に設定

と設定します。この時、

でReleaseを選択し、右側のプラットフォームを

と、”すべてのプラットフォーム”を選択して、設定を行ってください。これをやらないと、ストア審査用にアップロードするパッケージを各アーキテクチャ向けに作成することができません。

後はパッケージ作成時に、

と、x86、x64、ARM全てにチェック(ソリューション構成はもちろんRelease )して、パッケージを作成すればOKです。
もし、ここでDebugモードではコンパイル&実行できたのに、コンパイルできない、リンクできないといったメッセージが出る場合は、再度、全てのソースファイルが設定どおりになっているか確認してみてください。