Objective-C++でUnityのNativePluginを作り始めたが、stringの返却でUnityごとクラッシュしてしまう問題に遭遇した。その原因と解決方法を記しておく。
追記:コメントでご教授頂いたのですが、この方法だとメモリリークするようなので商用などデプロイする予定の開発では絶対に真似しないでください。機会があれば修正後のコードも出そうかと思いますが、多分先駆者がいると思うのでひとまずこのままで…。
(マネージド側で変換してくれるのでてっきり解放までしてくるのかと思いきや ←ちゃんと調べましょう)
原因
Objective-C++はinit
で始まる変数名を除いて基本的にautoreleaseされる。これにより、関数から返されるconst char*
がアクセスできずにUnityごと落ちてしまうようだ。
NSStringを使って文字列を作った場合は要注意だ。
解決方法
strdup()
を使って新たにメモリを確保すれば解決できる。自前でmalloc()
を使っても良いが、その必要があるケースは思いつかなかった。
MyUnityPlugin.mm
# import <Foundation/Foundation.h>
extern "C" {
const char * StrdupWay() {
NSString *result = @"subdup()を使ってUnityに文字列を返す";
return strdup([result UTF8String]);
}
const char * MallocWay() {
NSString *result = @"malloc()を使ってUnityに文字列を返す";
char* result_p = (char*)malloc(result.length + 1);
strcpy(result_p, [result UTF8String]);
return result_p;
}
}
UnityNativePluginScript.cs
using UnityEngine;
using System.Runtime.InteropServices;
public class UnityNativePluginScript : MonoBehaviour {
[DllImport("MyUnityPlugin")]
private static extern string StrdupWay();
[DllImport("MyUnityPlugin")]
private static extern string MallocWay();
// Use this for initialization
void Start () {
Debug.Log(StrdupWay());
Debug.Log(MallocWay());
}
}