OpenCV を C# から使うため、Cxxi でポーティングを試みたのだがうまくいかなかった。
何かの参考になるかもしれないので、ここにメモしておく。

Cxxi の使い方については、前回のエントリで簡単に書いたので、そちらを参考。

OpenCV はいくつかのモジュールで構成されている。
core, imgproc, calib3d, legacy, …

それぞれにヘッダファイルと DLL が用意されているので、
ヘッダに Cxxi をかければ、C# から利用できそうである。。

まずは、GCC-XML で ABI 解析する。
C++ のヘッダファイルを見つけられるように、g++ のインクルードディレクトリを設定する必要がある。

export CPLUS_INCLUDE_PATH=.:/c/MinGW64/x86_64-w64-mingw32/include:/c/MinGW64/lib/gcc/x86_64-w64-mingw32/4.6.1/include/c++:/c/MinGW64/lib/gcc/x86_64-w64-mingw32/4.6.1/include/c++/x86_64-w64-mingw32:/usr/local/include

GCC-XML はすべての builtin 関数をカバーしているわけではないので、SIMD 命令でエラーを起こしてしまう。
SIMD 命令を使わなければいいので、そのために以下を行った。

  • intrin.h を読み込ませない
  • 偽の intrin.h を作成して、それを読ませる、#include をコメントアウトする、など。

  • __MMX__, __SSE__, __SSE2__ を定義しない
  • コンパイルオプションで、-U__MMX__ -U__SSE__ -U__SSE2__ を設定する。

これで、GCC-XML は通る。

gccxml --gccxml-cxxflags "-shared -U__MMX__ -U__SSE__ -U__SSE2__" -fxml=core.xml /usr/local/include/opencv2/core/core.hpp

あとは Cxxi の generator を通せばいいのだが、謎の例外が飛んで上手くいかない。

generator -o=generated --lib=opencv_core233 core.xml
...

Unhandled Exception: System.TypeLoadException: Can not call MakeByRefType on a ByRef type
  at System.Type.MakeByRefType () [0x00000] in :0
  at Mono.Cxxi.CppType.m__21 (CppType t) [0x00000] in :0
  at (wrapper delegate-invoke) :invoke_Type__this___CppType (Mono.Cxxi.CppType)
  at Mono.Cxxi.CppType+c__AnonStoreyB.m__42 (System.Func`2 checkType) [0x00000] in :0
  at System.Linq.Enumerable+c__Iterator1D`1[System.Func`2[Mono.Cxxi.CppType,System.Type]].MoveNext () [0x00000] in :0
  at System.Linq.Enumerable+c__Iterator10`2[System.Func`2[Mono.Cxxi.CppType,System.Type],System.Type].MoveNext () [0x00000] in :0
  at System.Linq.Enumerable.First[Type] (IEnumerable`1 source, System.Func`2 predicate, Fallback fallback) [0x00000] in :0
  at System.Linq.Enumerable.FirstOrDefault[Type] (IEnumerable`1 source) [0x00000] in :0
  at Mono.Cxxi.CppType.ToManagedType () [0x00000] in :0
  at Generator.CppTypeToManaged (CppType t) [0x00000] in :0
  at Generator.CreateMembers () [0x00000] in :0
  at Generator.Run (System.String[] args) [0x00000] in :0
  at Generator.Main (System.String[] args) [0x00000] in :0
[ERROR] FATAL UNHANDLED EXCEPTION: System.TypeLoadException: Can not call MakeByRefType on a ByRef type
  at System.Type.MakeByRefType () [0x00000] in :0
  at Mono.Cxxi.CppType.m__21 (CppType t) [0x00000] in :0
  at (wrapper delegate-invoke) :invoke_Type__this___CppType (Mono.Cxxi.CppType)
  at Mono.Cxxi.CppType+c__AnonStoreyB.m__42 (System.Func`2 checkType) [0x00000] in :0
  at System.Linq.Enumerable+c__Iterator1D`1[System.Func`2[Mono.Cxxi.CppType,System.Type]].MoveNext () [0x00000] in :0
  at System.Linq.Enumerable+c__Iterator10`2[System.Func`2[Mono.Cxxi.CppType,System.Type],System.Type].MoveNext () [0x00000] in :0
  at System.Linq.Enumerable.First[Type] (IEnumerable`1 source, System.Func`2 predicate, Fallback fallback) [0x00000] in :0
  at System.Linq.Enumerable.FirstOrDefault[Type] (IEnumerable`1 source) [0x00000] in :0
  at Mono.Cxxi.CppType.ToManagedType () [0x00000] in :0
  at Generator.CppTypeToManaged (CppType t) [0x00000] in :0
  at Generator.CreateMembers () [0x00000] in :0
  at Generator.Run (System.String[] args) [0x00000] in :0
  at Generator.Main (System.String[] args) [0x00000] in :0