6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

UnityのNativePluginにNSStringをstringで返す方法

Last updated at Posted at 2018-01-22

Objective-C++でUnityのNativePluginを作り始めたが、stringの返却でUnityごとクラッシュしてしまう問題に遭遇した。その原因と解決方法を記しておく。

追記:コメントでご教授頂いたのですが、この方法だとメモリリークするようなので商用などデプロイする予定の開発では絶対に真似しないでください。機会があれば修正後のコードも出そうかと思いますが、多分先駆者がいると思うのでひとまずこのままで…。
(マネージド側で変換してくれるのでてっきり解放までしてくるのかと思いきや :sweat_drops: ←ちゃんと調べましょう)

原因

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());
    }

}

参考文献

6
2
1

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
6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?