using System; using System.Runtime.InteropServices; using System.Text; using UnityEngine; using UnityEngine.Events; public class FFI { #if UNITY_IOS || UNITY_TVOS public const string ImportName = "__Internal"; #else public const string ImportName = "rusty"; #endif } internal class StringHandle : SafeHandle { [DllImport(FFI.ImportName)] private static extern void FreeString(IntPtr handle); public StringHandle() : base(IntPtr.Zero, true) { } public override bool IsInvalid { get { return false; } } public string AsString() { int len = 0; while (Marshal.ReadByte(handle, len) != 0) { ++len; } byte[] buffer = new byte[len]; Marshal.Copy(handle, buffer, 0, buffer.Length); return Encoding.UTF8.GetString(buffer); } protected override bool ReleaseHandle() { FreeString(handle); return true; } } [System.Serializable] public class StatusChangedEvent : UnityEvent { } public class Rusty : MonoBehaviour { [DllImport(FFI.ImportName)] private static extern StringHandle DoSomeInterestingWork(int count, string content); public StatusChangedEvent OnStatusChanged; // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { } public void SayHello() { var rng = new System.Random(); OnStatusChanged.Invoke(DoSomeInterestingWork(rng.Next(1, 10), "Hello").AsString()); } }