在 enet 中指定回调函数
Specify callback function in enet
ENet 库有可以发送的数据包,并包含一个回调函数,一旦它发送完特定的数据包。
http://enet.bespin.org/structENetPacket.html#ad602d6b6b35ef88b2b2e080fa5c9dc3d
typedef struct _ENetPacket
{
size_t referenceCount; /**< internal use only */
enet_uint32 flags; /**< bitwise-or of ENetPacketFlag constants */
enet_uint8 * data; /**< allocated data for packet */
size_t dataLength; /**< length of data */
ENetPacketFreeCallback freeCallback; /**< function to be called when the packet is no longer in use */
void * userData; /**< application private data, may be freely modified */
} ENetPacket;
回调本身:
typedef void (ENET_CALLBACK * ENetPacketFreeCallback) (struct _ENetPacket *);
现在我想创建一个 class 来保存用于发送这些数据包的主机,并跟踪成功发送了多少数据包。
template<typename T>
class Sender {
public:
explicit Sender() { }
void send(T* data, int32_t length)
{
ENetPacket* packet = enet_packet_create(data, length, ENET_PACKET_FLAG_RELIABLE);
packet->freeCallback = callbackPacket;
enet_host_broadcast(m_server, 0, packet);
}
void callbackPacket(ENetPacket* packet)
{
--m_counter_packets_active;
}
};
这不编译:Error C3867 Sender<int32_t>::callbackPacket': non-standard syntax; use '&' to create a pointer to member
当我尝试时
packet->freeCallback = &this->callbackPacket;
我得到Error C2440 '=': cannot convert from 'void (Sender<int32_t>::* )(ENetPacket *)' to 'ENetPacketFreeCallback'
我只是不明白当数据包完成后调用 Sender 对象的方法的正确代码是什么。
好的,这很常见。首先,您不能以这种方式调用非静态成员方法,不能直接调用。屁股疼
但是那个回调结构有一个 userData 字段。这就是我们要使用的。
void send(T* data, int32_t length) {
ENetPacket* packet = enet_packet_create(data, length, ENET_PACKET_FLAG_RELIABLE);
packet->freeCallback = &Sender::myStaticMethod;
packet->userData = this; // This is part of the magic
enet_host_broadcast(m_server, 0, packet);
}
static void myStaticMethod(ENetPacket * packet) {
Sender * sender = static_cast<Sender *>(packet->userData);
sender-> callbackPacket(packet);
}
换句话说——将 this
存储为您的用户数据。回调使用静态方法,让他反过来调用你真正的回调。
ENet 库有可以发送的数据包,并包含一个回调函数,一旦它发送完特定的数据包。
http://enet.bespin.org/structENetPacket.html#ad602d6b6b35ef88b2b2e080fa5c9dc3d
typedef struct _ENetPacket
{
size_t referenceCount; /**< internal use only */
enet_uint32 flags; /**< bitwise-or of ENetPacketFlag constants */
enet_uint8 * data; /**< allocated data for packet */
size_t dataLength; /**< length of data */
ENetPacketFreeCallback freeCallback; /**< function to be called when the packet is no longer in use */
void * userData; /**< application private data, may be freely modified */
} ENetPacket;
回调本身:
typedef void (ENET_CALLBACK * ENetPacketFreeCallback) (struct _ENetPacket *);
现在我想创建一个 class 来保存用于发送这些数据包的主机,并跟踪成功发送了多少数据包。
template<typename T>
class Sender {
public:
explicit Sender() { }
void send(T* data, int32_t length)
{
ENetPacket* packet = enet_packet_create(data, length, ENET_PACKET_FLAG_RELIABLE);
packet->freeCallback = callbackPacket;
enet_host_broadcast(m_server, 0, packet);
}
void callbackPacket(ENetPacket* packet)
{
--m_counter_packets_active;
}
};
这不编译:Error C3867 Sender<int32_t>::callbackPacket': non-standard syntax; use '&' to create a pointer to member
当我尝试时
packet->freeCallback = &this->callbackPacket;
我得到Error C2440 '=': cannot convert from 'void (Sender<int32_t>::* )(ENetPacket *)' to 'ENetPacketFreeCallback'
我只是不明白当数据包完成后调用 Sender 对象的方法的正确代码是什么。
好的,这很常见。首先,您不能以这种方式调用非静态成员方法,不能直接调用。屁股疼
但是那个回调结构有一个 userData 字段。这就是我们要使用的。
void send(T* data, int32_t length) {
ENetPacket* packet = enet_packet_create(data, length, ENET_PACKET_FLAG_RELIABLE);
packet->freeCallback = &Sender::myStaticMethod;
packet->userData = this; // This is part of the magic
enet_host_broadcast(m_server, 0, packet);
}
static void myStaticMethod(ENetPacket * packet) {
Sender * sender = static_cast<Sender *>(packet->userData);
sender-> callbackPacket(packet);
}
换句话说——将 this
存储为您的用户数据。回调使用静态方法,让他反过来调用你真正的回调。