Unity中ROS订阅回调Delegate Target为null导致回调未触发问题
问题:Unity中通过反射创建ROS订阅回调时Delegate Target为null导致回调不触发
我在Unity中使用ROS或ZMQ与设备通信,为实现无需重构代码即可适配两种通信方式,创建了接口类连接主代码与通信库。但订阅ROS话题时,回调函数从未被调用,排查发现即使创建Delegate时指定了this,其Target仍为null。
主类RobotCommand中创建订阅的代码
// ... (class RobotCommand) try { var defineSubscriberMethod = m_interface.GetType().GetMethod("DefineSubscriber"); var genericMethod = defineSubscriberMethod.MakeGenericMethod(m_interface.TypeFloatArrayAlias); var delegateType = typeof(Action<>).MakeGenericType(m_interface.TypeFloatArrayAlias); var methodInfo = this.GetType().GetMethod(nameof(UpdateVirtualRobotJointsCallback), BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); if (methodInfo == null) throw new Exception("Method 'UpdateVirtualRobotJointsCallback' not found."); Debug.Log($"Method Info: {methodInfo.Name} Target: {this.GetType().Name}"); // 输出:Method Info: UpdateVirtualRobotJointsCallback Target: RobotCommand Delegate callbackDelegate = Delegate.CreateDelegate(delegateType, this, methodInfo); Debug.Log($"Delegate Target: {callbackDelegate.Target}, Method: {callbackDelegate.Method}"); // 输出:Delegate Target: null, Method: Void UpdateVirtualRobotJointsCallback(RosMessageTypes.Std.Float32MultiArrayMsg) genericMethod.Invoke(m_interface, new object[] { Const.ROS_NAMESPACE + "robot_joint_values", callbackDelegate }); } catch (Exception e) { Debug.LogError($"Error invoking DefineSubscriber: {e.Message}"); } } public void UpdateVirtualRobotJointsCallback(Float32MultiArrayMsg msg) { Debug.Log("called"); StartCoroutine(m_controller.MoveRobot_Coroutine(m_interface.ToFloatArray(msg))); }
接口类中的DefineSubscriber方法
public override void DefineSubscriber<T>(string topic, Action<T> callback) { try { Debug.Log($"Delegate Callback: Target={callback.Target}, Method={callback.Method}"); // 输出:Delegate Callback: Target=null, Method=Void UpdateVirtualRobotJointsCallback(RosMessageTypes.Std.Float32MultiArrayMsg) Type msgType = typeof(T); // _node 是 ROS 对象(ROSConnection.GetOrCreateInstance()) var subscribeMethod = _node.GetType().GetMethod("Subscribe").MakeGenericMethod(msgType); subscribeMethod.Invoke(_node, new object[] { topic, callback }); _subscriberList[topic] = (x => callback((T)x), msgType); Debug.Log($"Subscriber created for topic: {topic} with message type: {msgType.Name}"); } catch (Exception e) { Debug.LogError($"Error while defining subscriber for topic {topic}: {e.Message}"); } }
正常工作的订阅创建参考代码
void Start() { ROSConnection.GetOrCreateInstance().Subscribe<Float32MultiArrayMsg>(m_topicName, UpdateVirtualRobotJointsCallback); } // Update is called once per frame void Update() { } void UpdateVirtualRobotJointsCallback(Float32MultiArrayMsg msg) { Debug.Log("called"); StartCoroutine(xarmController.MoveRobot_Coroutine(new List<float>(msg.data))); }
调试时确认Delegate的Target始终为null,推测这是回调未被调用的根本原因。
内容的提问来源于stack exchange,提问作者Dark Patate
相关产品推荐
相关产品推荐

