渋谷ほととぎす通信

エンジニア社長によるUnityとAIのブログ & エンジニアの生存戦略

【Unity】C#とC++間でint型のデータを送り合う方法

【Unity】C#とC++間でint型のデータを送り合う方法

こんにちは、Unityエンジニアのオオバです。

お悩みさん
お悩みさん
  • int型をC#からC++に送ってみたい
  • オオバ
    オオバ
    本記事ではこれらの悩みを解決します。

    C#とC++間のデータやりとりを実装したことありますか?

    Unityが提供する機能を普通に使っているだけだと、あまり出てこないシチュエーションかも知れません。 Unityが提供していない機能にアクセス といったUnityの外へ一歩出ようとするとC++や別の言語が必要になります。

    今回はC#とC++間のデータのやり取りシリーズ2回目。C#からC++に対して int型 を渡してみます。

    本記事はWindows環境でのみ動作します。Mac環境では動作しないのでご注意ください。

    C#からC++にデータを送るための環境構築はこちらの記事を参考にしてみてください。

    int型C++とC#で変換無しで受け取り可能

    最初に結論ですがint型の場合C#/C++間のデータやり取りは簡単です。特にデータ変換の必要がなく そのまま送ることができます。

    よくC#からC++にデータを送信する際、 「マーシャリング」 というキーワードを聞いたことがあるかもしれません。

    しかしint型の場合マーシャリングは不要です。どういうデータがそのまま送信でき、どういうデータができないのか本記事では解説していきます。

    まずはC#/C++間のデータのルールを知って理解を深めていきましょう。

    👉DOTweenの教科書を読んでUnityアニメーションをプログラミングしてみよう!

    int型がC#/C++間で簡単に扱える理由

    冒頭の通りint型はC#/C++間では特に意識することなくデータ送信できます。理由はint型がBlittable型だからです。Blittable(ブリッタブル)型とはデータ変換を必要としない型のこと。

    もっと具体的に言うと、C#とC++どちらでも共通して使われる型がBlittable型ということです。

    例えば以下がBlittable型です。

    • int
    • uint
    • float
    • double
    • Blittable型で構成された構造体

    などなど。

    このようにint型がC#/C++間で簡単に扱える理由がわかったと思います。では具体的にC#からC++にint型を渡す方法を解説していきます。

    int型を受け取るC++側の処理

    最初にint型データを受け取るC++側の処理を実装していきます。

    C#と同じint型で受け取れるためC++のコードはとてもシンプルです。ではソースコードを確認していきましょう。

    💻ソースコード : TestDll.cpp
    #include <iostream>
    
    extern "C" __declspec(dllexport) int Additive(int a, int b)  
    {
        return a + b;  
    }
    
    

    以前の記事で文字列をC#からC++に送信した際は ポインタ で受け取りました。しかし今回はint型で受け取れます。

    C#からint型を渡す際はポインタではなく値型でそのまま受け取れるのです。

    int型を送信するC#側の処理

    次にC#側の実装をしていきます。早速ソースコードの紹介です。AwakeタイミングでC++側で宣言した Additive 関数に「24」と「5」というデータを送ってみました。

    [DllImport("TestDll.dll", CallingConvention = CallingConvention.Cdecl)]  
    static extern int Additive(int a, int b);  
    
    void Awake()  
    {
        int result = Additive(24, 5);  
        Debug.Log(result);  
    }
    

    コードの通り特にデータの型を意識することなくそのままC++に送信することが可能です。

    int型以外のBlittable型の送信方法は?

    Blittable型はint型問わずそのままC++へ値を送信できます。例として、Blittable型の1つであるfloat型のデータをC#からC++に送ってみましょう。

    float型を受け取るC++側の処理

    まずはfloat型のデータを受け取るCLL側の実装からしていきます。

    💻ソースコード : TestDll.cpp
    #include <iostream>
    
    extern "C" __declspec(dllexport) float AdditiveFloat(float a, float b)  
    {
        return a + b;  
    }
    

    ほとんどint型のときと同様です。受け取る型が int から float に変わりました。

    float型を送信するC#側の処理

    C#側も基本的にint型のときと同じです。 int から float へ型が変わりました。

    [DllImport("TestDll.dll", CallingConvention = CallingConvention.Cdecl)]  
    static extern void AdditiveFloat(float a, float b);  
    
    void Awake()  
    {
        float result = AdditiveFloat(3.14f, 12.5f);  
        Debug.Log(result);  
    }
    

    このようにfloat型をC#からC++に送信できます。

    Blittable型はそのまま送信可能

    繰り返しになりますが、int型やfloat型は Blittable型 です。Blittable型はデータ変換を必要とせずにC#/C++間でデータのやり取りができるのです。

    ちなみにC#では以下がBlittable型です。

    • System.Byte
    • System.SByte
    • System.Int16
    • System.UInt16
    • System.Int32
    • System.UInt32
    • System.Int64
    • System.UInt64
    • System.IntPtr
    • System.UIntPtr
    • System.Single
    • System.Double

    まとめ : C#からC++にintを渡す方法

    C#とC++間でのint型やり取りは、とくに意識することはありません。

    • C#、C++ともにint型を定義
    • int型の値をそのまま送信
    • Blittable型はそのまま送信可

    C#/C++間でやり取りする独特な記述に慣れていきましょう。

    int型は特にC#/C++を意識することなくデータ送信できました。次はC++側で読み取れるデータに変換するマーシャリングを行って配列データを送信してみましょう。よりC#/C++間の理解が深まります。

    こちらの記事で詳しく解説しているのでぜひ読んでみてください。

    最後に今回作成したサンプルコードを共有しますので参考にしてみてください。

    オススメ記事
    検証環境
    • Visual Studio Community 2022 (64 ビット) v17.13.1
    • Windows11
    • Unity6000.0.39f1
    参考サイト