MEFは.NETライブラリですから、ピュアなC++では使えないけど「ほぼC++」なC++/CLIなら何とかなるんじゃないかと。MSDNで見つけたドキュメントを手掛かりに MEF:はじめの一歩をC++/CLIで踏み出しました。
DLL、COM、そしてMEF
re-buildなしに機能拡張する手段はずっと以前からあります、WindowsではDLLがおなじみですね。DLLの中には関数名を埋め込むことができ、LoadLibrary()でDLLを読み込んだ後GetProcAddress()に関数名を与えれば、当該関数のアドレスが手に入り/呼び出すことができます。ただし手に入るのは関数のアドレスだけで、引数や戻り値に関する情報はもらえないので決め打ちにするしかありませんし、関数/変数をひとまとめにしたオブジェクト(クラス)を定義して呼び出すこともできません。そこでオブジェクトを定義し呼び出せるCOMの登場となるわけです。が、COMってシロモノは作る側も使う側もかなりややこしく、決して"お手軽"とは言い難い。
MEFによる機能拡張では、拡張したい機能をinterfaceで定義します。機能を提供する側はそのinterfaceを実装したクラスを作ってExport(外に出す/公開する)し、対して機能を利用する側はinterfaceの受け皿を用意して、そこにImport(取り込む)します。MEFは提供(Export)側と利用(Import)側との仲介を行い、両者を結びつけてくれます。Export/Importはクラスや変数にアトリビュート:[Export(~)]/[Import(~)]を付記するだけなので、COMに比べて圧倒的に簡単です。
能書きはこれくらいにして、サンプルをお見せしましょう。
二項電卓:Windows Formアプリケーションの作り方
サンプルに用意したのは、こんな外観の電卓アプリケーション。
int値を2つ入力し、演算子を選んで「=」ボタンを押すと答えが表示される、あまりのショボさに電卓と呼ぶのも恥ずかしい二項電卓をWindows Formsで作りました。ComboBoxに列挙される演算子をMEFで追加しようという魂胆です。
Visual Studio 2012以降、C++/CLIによるCLRフォームアプリケーションのひな型がプロジェクトテンプレートから消えてしまいました。けども作れなくなったわけではありません。ちょっと寄り道になりますが、フォームアプリケーションの作り方を紹介しておきます。
まず、プロジェクトテンプレートでは「空のCLRプロジェクト」を選択します。プロジェクト名は"SimpleCalculator"としましょう。
つぎにメニュー:プロジェクト/新しい項目の追加...でWindowsフォームを追加します。フォーム名は"CalculatorForm"で。
さらにメニュー:プロジェクト/新しい項目の追加...でC++ファイル(.cpp)、名前を"SimpleCalculator.cpp"としてコードを追加します。これがアプリケーションの入り口であるmain()です。
#include "CalculatorForm.h" using namespace System; [STAThread] int main(array<String^>^ args) { using namespace System::Windows::Forms; Application::EnableVisualStyles(); Application::SetCompatibleTextRenderingDefault(false); Application::Run(gcnew SimpleCalculator::CalculatorForm()); return 0; }
残るはプロジェクト・プロパティの設定。構成プロパティ/リンカー/システム/サブシステムをWindows(/SUBSYSTEM:WINDOWS)に、構成プロパティ/リンカー/詳細設定/エントリポイントをmainとします。
ここでビルド/実行し、空っぽのCalculatorFormが現れたら出来上がり。2つのTextBoxとComboBox、Buttonそして大きなLabelを貼り付け、Button-Clickハンドラを用意して電卓フォームの完成です。
最後にもう一つ、MEFを提供するアセンブリ:System.ComponentModel.Compositionへの参照を追加しておきます。