はじめに
ネイティブプラグインの作成時にネイティブ側から Unity の Debug.Log()
を呼んでデバッグしたくなるときが多々あります。以下のエントリ(英語)で方法が紹介されていたのでやってみました。
ざっくり3行
環境
- Mac OS X 10.10 / Windows 8.1
- Unity 5.3.0f4
具体的なコード
C++ 側
こんな関数を C# 側へ晒します。
#if defined(_WIN32) || defined(_WIN64) #define UNITY_INTERFACE_EXPORT __declspec(dllexport) #else #define UNITY_INTERFACE_EXPORT #endif extern "C" { using debug_log_func_type = void(*)(const char*); namespace { debug_log_func_type debug_log_func = nullptr; } void debug_log(const char* msg) { if (debug_log_func != nullptr) debug_log_func(msg); } UNITY_INTERFACE_EXPORT void set_debug_log_func(debug_log_func_type func) { debug_log_func = func; } UNITY_INTERFACE_EXPORT void debug_log_test() { debug_log("hogehoge"); } }
set_debug_log_func()
を C# 側から呼び出し Debug.Log()
を行う関数ポインタをセットします。その後にセットされた関数を呼び出す debug_log_test()
を C# から呼び出し、Unity のコンソールに hogehoge
が出力されれば成功です。
C# 側
以下の様なコードを用意します。
using UnityEngine; using System; using System.Runtime.InteropServices; public class NativeDebugLog : MonoBehaviour { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void DebugLogDelegate(string str); DebugLogDelegate debugLogFunc = msg => Debug.Log(msg); [DllImport ("unity_debug_log")] public static extern void set_debug_log_func(IntPtr ptr); [DllImport ("unity_debug_log")] public static extern void debug_log_test(); void Start() { var callback = new DebugLogDelegate(debugLogFunc); var ptr = Marshal.GetFunctionPointerForDelegate(callback); set_debug_log_func(ptr); debug_log_test(); } }
UnmanagedFunctionPointerAttribute
と Marshal.GetFunctionPointerForDelegate()
を使って関数ポインタを取り出してセットしています。
結果
実行すると無事 hogehoge
と出力されます。
もっと簡単な方法
以下のエントリを読むとそのままデリゲートを渡しても問題ないようです。
なので C# 側のコードを以下のように書き換えても動きます。
using UnityEngine; using System.Runtime.InteropServices; public class NativeDebugLog : MonoBehaviour { public delegate void DebugLogDelegate(string str); DebugLogDelegate debugLogFunc = msg => Debug.Log(msg); [DllImport ("unity_debug_log")] public static extern void set_debug_log_func(DebugLogDelegate func); [DllImport ("unity_debug_log")] public static extern void debug_log_test(); void Start() { set_debug_log_func(debugLogFunc); debug_log_test(); } }
おわりに
デバッグにも便利ですし、他にも色々と使えそうです。