読者です 読者をやめる 読者になる 読者になる

mono対応に書き換え中

またまた内部仕様が変わりまくりです。

既にコア部分の対応は大体終わっていて、windows版のmono2.4では動作を確認できました。

残るはMLやBlobの部分で、この辺りはC++/CLIで実装してあるので、これを全部やめてC#で書き直さなければなりません。しかし、ここはOpenCV側の実装がC++なのでDllImportはかなり厳しく、C++のクラスのメンバ関数を単純な関数として公開させるような薄いネイティブのラッパーを作る必要があります。面倒。



基本的な手法は以下のようになります。
例えば以下のクラスHogeのラッパーを作りたいとして、

class Hoge
{
public:
    Hoge();
    ~Hoge();
    int fuga(const char* str);
};

このようなdllexportの関数を定義します。

CVAPI(Hoge*) Hoge_new()
{
    return new Hoge();
}
CVAPI(void) Hoge_delete(Hoge* p)
{
    delete p;
}
CVAPI(int) Hoge_fuga(Hoge* p, const char* str)
{
    return p->fuga(str);
}

なおここでCVAPI(type)は

extern "C" __declspec(dllexport) type __cdecl

のように展開されるOpenCVのマクロです。


これを、C#側では以下のようにしてDllImportして使います。

[DllImport("hoge.dll")]
extern static IntPtr Hoge_new();
[DllImport("hoge.dll")]
extern static void Hoge_delete(IntPtr p);
[DllImport("hoge.dll")]
extern static int Hoge_fuga(IntPtr p, [MarshalAs(UnmanagedType.LPStr)] string str);

また、extern "C" のためにC++のクラスや構造体を値で返せないので、以下のような関数はそのままの形式では公開できません。

Hoge get_hoge(int i, int j);

この場合は、引数にポインタ渡ししてそこに入れてあげる形になります。

CVAPI(void) get_hoge_export(Hoge* out, int i, int j)
{
    *out = get_hoge(i, j);
}


Monoプログラミング .NET/C#とMono for AndroidによるAndroidアプリケーション開発

Monoプログラミング .NET/C#とMono for AndroidによるAndroidアプリケーション開発