やりたいこと
C++プロジェクトから"return"で値や文字列を渡して、Unity内で使用したい。
色々試行錯誤してみて、自分の中で方法が確立されたのでメモ。
渡したい情報は「数値、浮動小数点、真偽値、文字列」
C++からint
, double
, bool
, const char*
として渡す。
環境
・Visual Studio 2022 Community
・C++ 14
・C♯ 9.0
・Unity 6000.0.37f1
まず .dllプロジェクトを作成する。
今回はVisual Studio 2022 の Community版を使用する。
新しいプロジェクトの作成(N) → Windowsデスクトップウィザード
→ パス&プロジェクト名設定 → Windowsデスクトッププロジェクト
に進み、
アプリケーションの種類(T): ダイナミックライブラリ(.dll)
追加のオプション: 空のプロジェクト(E)
と設定する。
今回はプロジェクト名をReturnValue
としている。
C++側
ReturnValue.h
とReturnValue.cpp
を作成し、以下のように記述する。
ReturnValue.h
#pragma once
#ifdef RETURNVALUE_EXPORTS
# define EXPORT __declspec(dllexport)
#else
# define EXPORT __declspec(dllimport)
#endif
extern "C" __declspec(dllexport) int ReturnInt();
extern "C" __declspec(dllexport) double ReturnDouble();
extern "C" __declspec(dllexport) bool ReturnBool();
extern "C" __declspec(dllexport) const char* ReturnString();
ReturnValue.cpp
#include "ReturnValue.h"
__declspec(dllexport) int ReturnInt()
{
return 123;
}
__declspec(dllexport) double ReturnDouble()
{
return 1.23;
}
__declspec(dllexport) bool ReturnBool()
{
return true;
}
__declspec(dllexport) const char* ReturnString()
{
return "Hello, C++";
}
リリースビルドが無事に通ると、x64/Release
の中にReturnValue.dll
が生成される。
Unity側
Assets
フォルダの中に分かりやすいようにPlugins
フォルダを作成し、生成したReturnValue.dll
を入れる。
次に適当なC♯ファイルを作成し以下のように記述する。
(今回はファイル名をTest
としている。)
Test.cs
using System;
using System.Runtime.InteropServices; // DllImport用
using UnityEngine;
public class Test : MonoBehaviour
{
[DllImport("ReturnValue.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int ReturnInt();
[DllImport("ReturnValue.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern double ReturnDouble();
[DllImport("ReturnValue.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern bool ReturnBool();
[DllImport("ReturnValue.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr ReturnString();
// 文字列用
private string str;
void Awake()
{
Debug.Log($"int: {ReturnInt()}");
Debug.Log($"double: {ReturnDouble()}");
Debug.Log($"bool: {ReturnBool()}");
IntPtr p = ReturnString();
str = Marshal.PtrToStringAnsi(p);
Debug.Log($"string: {str}");
}
}
実行結果
int: 123
UnityEngine.Debug:Log (object)
Test:Awake () (at Assets/Scripts/Test.cs:23)
double: 1.23
UnityEngine.Debug:Log (object)
Test:Awake () (at Assets/Scripts/Test.cs:24)
bool: True
UnityEngine.Debug:Log (object)
Test:Awake () (at Assets/Scripts/Test.cs:25)
string: Hello, C++
UnityEngine.Debug:Log (object)
Test:Awake () (at Assets/Scripts/Test.cs:29)