如何在ENet中为数据包指定绑定Sender类实例的回调函数
问题根因
类的非静态成员函数默认会携带隐式的this指针参数,和ENetPacketFreeCallback要求的C风格函数签名(仅接收ENetPacket*一个参数)不匹配,因此无法直接转换赋值。
解决方法
利用ENetPacket结构体提供的userData字段存储当前Sender实例的指针,再通过静态成员函数作为中间回调,从userData拿到实例后执行对应逻辑即可,修改后可运行的完整代码如下:
template<typename T> class Sender { public: explicit Sender() = default; void send(T* data, int32_t length) { ENetPacket* packet = enet_packet_create(data, length, ENET_PACKET_FLAG_RELIABLE); // 静态成员函数无隐式this指针,和C风格回调签名匹配 packet->freeCallback = &Sender::staticPacketCallback; // 把当前Sender实例指针存入userData字段,供回调时读取 packet->userData = this; // 发送前先把活跃计数+1,和回调的-1对应 ++m_counter_packets_active; enet_host_broadcast(m_server, 0, packet); } private: static void staticPacketCallback(ENetPacket* packet) { // 从userData取回Sender实例指针 auto* senderInstance = static_cast<Sender<T>*>(packet->userData); // 执行实例的计数统计逻辑 --senderInstance->m_counter_packets_active; // 若数据包携带自定义需要手动释放的资源,可以在这里执行释放逻辑 } ENetHost* m_server = nullptr; // 注意按实际场景初始化host实例 size_t m_counter_packets_active = 0; };
注意事项
需要保证Sender实例的生命周期长于所有未完成发送的数据包,否则回调时访问userData会触发野指针错误。
内容的提问来源于stack exchange,提问作者SinisterMJ
相关产品推荐
相关产品推荐

