using System; using System.Collections.Generic; using System.Runtime.InteropServices; using AOT; using UnityEngine; using UnityEngine.Events; using System.Threading; namespace MySerialPortInterface { [System.Serializable] public class SerialPortSystemEventObject : UnityEngine.Events.UnityEvent { } public class SerialPortInterface : MonoBehaviour { private const string SERIALPORTAPI = "com/example/serialport/serialport_api"; //java对象 private AndroidJavaObject serialPortApiObj = null; public string ComPort = "/dev/ttyS0"; public int BaudRate = 115200; public string DeviceName = "ttyS0"; int serialPortId = -1; // 使用 UnityEvent 使事件公开在 Inspector 中 [System.Serializable] public class SerialPortUpdateEvent : UnityEvent { } [HideInInspector] public SerialPortSystemEventObject SystemEventObject = new SerialPortSystemEventObject(); // 在 Inspector 中可以赋值的事件 public SerialPortUpdateEvent OnSerialPortUpdateEvent; private SynchronizationContext _syncContext; void Awake() { // 获取主线程的 SynchronizationContext _syncContext = SynchronizationContext.Current; try { // 创建 serialPortApi 对象 serialPortApiObj = new AndroidJavaObject(SERIALPORTAPI); } catch (Exception e) { Debug.LogError("UVC_MANAGER Exception: " + e.Message); } } void Start() { //初始化端口 //Open(); } public void Open() { //如果已经注册过了 if (serialPortId != -1) return; serialPortId = serialPortApiObj.Call("initSerialPort", ComPort, BaudRate); if (serialPortId != -1) { Debug.Log("initSerialPort 初始化成功!"); if (SystemEventObject != null) SystemEventObject.Invoke(this, "OPENED"); //注册c回调 Add(this); } else { Debug.LogError("initSerialPort 初始化失败!"); if (SystemEventObject != null) SystemEventObject.Invoke(this, "OPEN_ERROR"); } //SendTest(); } private void OnDestroy() { if (Application.platform == RuntimePlatform.Android) { Remove(this); Close(); } } public void SendTest() { serialPortApiObj.Call("SendTest"); } public void Close() { serialPortApiObj.Call("closeSerialPort"); if (SystemEventObject != null) SystemEventObject.Invoke(this, "CLOSED"); serialPortId = -1; } public void Write(byte[] data) { // // Debug.Log("Unity调用Android的sendSerialPort方法"); sbyte[] mySByte = new sbyte[data.Length]; for (int i = 0; i < data.Length; i++) { if (data[i] > 127) mySByte[i] = (sbyte)(data[i] - 256); else mySByte[i] = (sbyte)data[i]; } serialPortApiObj.Call("sendSerialPort", new object[] { mySByte, data.Length }); Debug.Log($"[SerialPortInterface]Write:{ComPort}, data: {BitConverter.ToString(data)},length: {data.Length}"); } public void OnSerialPortUpdate(byte[] buffer, int size) { // 处理数据 Debug.Log($"[SerialPortInterface]回调:{ComPort}, data: {BitConverter.ToString(buffer)},length: {buffer.Length} ,size: {size}"); // 触发事件 OnSerialPortUpdateEvent?.Invoke(buffer, size); } [UnmanagedFunctionPointer(CallingConvention.StdCall)] public delegate void SerialPortUpdateDelegate(Int32 id, IntPtr buffer, int size); [DllImport("SerialPortCustom")] private static extern void RegisterSerialPortUpdateCallback(Int32 id, SerialPortUpdateDelegate callback); [DllImport("SerialPortCustom")] private static extern void UnregisterSerialPortUpdateCallback(Int32 id, SerialPortUpdateDelegate callback); //记录MyUVCInterface private static Dictionary mSerialPortInterfaces = new Dictionary(); private static SerialPortUpdateDelegate serialPortUpdateDelegate; //注册回调事件 public static void Add(SerialPortInterface mySerialPortInterface) { Int32 id = mySerialPortInterface.serialPortId; serialPortUpdateDelegate = new SerialPortUpdateDelegate(SerialPortUpdateHandler); mSerialPortInterfaces.Add(id, mySerialPortInterface); RegisterSerialPortUpdateCallback(id, serialPortUpdateDelegate); } //移除回调事件 public static void Remove(SerialPortInterface mySerialPortInterface) { Int32 id = mySerialPortInterface.GetHashCode(); UnregisterSerialPortUpdateCallback(id, serialPortUpdateDelegate); mSerialPortInterfaces.Remove(id); } //数据更新时候回调 [MonoPInvokeCallback(typeof(SerialPortUpdateDelegate))] // 修改回调处理 private static void SerialPortUpdateHandler(Int32 id, IntPtr buffer, int size) { byte[] managedBuffer = new byte[size]; Marshal.Copy(buffer, managedBuffer, 0, size); // Debug.Log($"Received buffer in C#: {BitConverter.ToString(managedBuffer)}, size: {size}, buffer.Length: {managedBuffer.Length}"); var mySerialPortInterface = mSerialPortInterfaces.ContainsKey(id) ? mSerialPortInterfaces[id] : null; // 使用 SynchronizationContext 将操作调度到主线程 mySerialPortInterface?.EnqueueOnMainThread(() => mySerialPortInterface.OnSerialPortUpdate(managedBuffer, size)); } // 调度操作到主线程 public void EnqueueOnMainThread(Action action) { // 如果 _syncContext 为 null,可能是没有正确初始化,可以检查并加以处理 if (_syncContext != null) { _syncContext.Post(_ => action(), null); } else { // 如果找不到 SynchronizationContext,使用 Unity 的主线程调度 UnityMainThreadDispatcher.Instance().Enqueue(action); } } } }