コマンドラインからコンパイル

今頃する話題なのか?(^^;

exeを作る

$ cl /clr:safe /Fexxx.exe yyy.cpp

dllを作る

$ cl /clr:safe /LD /Fexxx.dll yyy.cpp

/clrだけでマネージドなアセンブリになりますが、Monoで実行するには/clr:safeにする必要があります。(詳しく調べてないけど・・・)

型の公開
C++/CLIのデフォルトはprivateなので公開する場合はpublicにします。

namespace mylib {
  // アセンブリの外へ公開
  public ref class Foo {};
  // アセンブリ内のみ
  private ref class Bar {};
}

STL.NETとコレクションの相互運用

STLは素晴らしいライブラリですが、.NET Frameworkにもコレクション(System.Collection.Generic)があり、C++/CLI以外の言語も使う場合にはコレクションを使った方が何かと都合が良かったりします。STL.NETではその辺にも配慮されています。

void test()
{
    vector<int> v;

    v.push_back(1);
    v.push_back(2);
    v.push_back(3);

    // to_arrayでarray型へ変換
    array<int>^ intArray1 = v.to_array();

    // vectorはICollectionを実装している
    array<int>^ intArray2 = gcnew array<int>(v.Count);
    v.CopyTo(intArray2, 0);

    // for eachも可
    for each (int n in v) 
        Console::WriteLine(n);

    // ListのコンストラクタはIEnumerableを取る
    List<int>^ l = gcnew List<int>(%v);
}

このようにSTL.NETのコンテナクラスはIEnumerable/IEnumerator等を実装しています。

ところで上記を書いている時に、

vector v;
...
List^ l = gcnew List(v);

としてしまい、コンパイルが通らずに嵌りまくりました。トラッキングハンドルを渡さないといけないことをつい忘れてしまいます。もし、高価なリソースを扱わないのなら、

vector^ v = gcnew vector();

と、スタック割り当ては控えるようにした方が混乱しなくて良いかも知れませんね。