0
0

More than 3 years have passed since last update.

Unityプラグイン/C++

Last updated at Posted at 2020-06-08

環境

OS: windows10 pro 64bit
IDE: VS2017 free
Unity :
OpenCV + aruce : ソースからビルドの後半参照
OpenCV : OpenCV Plus Unity(無料版)

Unityプラグイン

gitignore

プラグインのひな型

Unityプロジェクト設定

a. Asset直下にPluginsフォルダを作成する。「\Assets\Plugins\x86_64」
b. 呼び出しテスト

extern "C"
{
    int EXPORT_API PrintNumber() {
        return 999;
    }
}

int main_dll(int id)
{
    const char* lpBuffer = "hogehoge.dll";
    HMODULE hModule = LoadLibrary((LPCSTR)lpBuffer);
    if (hModule == NULL) {
        assert(0);
        return 0;
    }
    g_hModule = hModule;//HMODULE

    FUNC lpFunc = (FUNC)GetProcAddress(hModule, "PrintNumber");
    return lpFunc();
}

C#

using System.Runtime.InteropServices;

    [DllImport("plugin")]
    private static extern int PrintNumber();

    // Start is called before the first frame update
    void Start()
    {
        Debug.Log(PrintNumber());   
    }

<結果>
image.png

プラグインをx64ビルドしたらUnityもx64にしてください。
image.png

unsafe/mcs.rsp

メモリコピー高速化等でunsafeは有効にした方がよいです。
smcs.rspは名称変更

image.png

インターフェース

C++とC#のインターフェースは色々あります。

マーシャルコピー

Marshal.Copy メソッド

データ受け渡し(プラグイン -> C#)

プラグインC++の方
EXPORT_API void* GetColorBuffer(int* len)

これをC#から呼んでデータを保持する。メモリコピーが発生する。C++とC#のメモリ管理の違いから必要になる。高速化もできるけど面倒。

{
    int len = 0;
    IntPtr colBuff = GetColorBuffer(ref len);
    byte[] dst = new byte[len];

    Marshal.Copy(colBuff, dst, 0, len); // CV_8UC4

    _Texture.LoadRawTextureData(dst);
    _Texture.Apply();

    if (m_image != null)
        m_image.material.mainTexture = _Texture;
}

データ受け渡し(プラグイン <= C#)


int len = 10;
IntPtr data = Marshal.AllocHGlobal(len*1 );

byte[] src= new byte[len];
for( int i = 0; i< 10; i++){
src[i] = (byte)(i+30);
}
Marshal.Copy(src,0, data, len);//src ,dst
int result = SetColorBuffer(ref len, data);
Debug.Log(string.Format("{0}\n",result));


    //private static extern int SetColorBuffer( ref int len, IntPtr data );
    EXPORT_API int SetColorBuffer( int* len, void* _data )
    {
        int tlen = *len;
        BYTE* data = (BYTE*)_data;
        int sum = 0;
        for( int i = 0;i < tlen; i++){
            printf( "%x", data[i] );
            sum += data[i];
        }

        return sum+1;
    }

ビルド後イベント

pluginはVSでビルドあとに自動でUnity-Assets-Pluginsにコピーするとよいです。
Unityは再起動が必要です。ホットリロードの方法もあるけど不安定になった。
パス指定は¥マーク2個のターミネートで。
駄目なときは絶対パスでかく。

image.png

デバッグ

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0