0

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 *);

现在我想创建一个类来保存用于发送这些数据包的主机,并跟踪成功发送了多少数据包。

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 对象方法的数据包的正确代码是什么。

4

1 回答 1

1

好吧,这很常见。首先,您不能以这种方式调用非静态成员方法,而不是直接调用。屁股疼。

但是该回调结构有一个 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为您的用户数据。对回调使用静态方法,并让他将其转过来调用您的真正回调。

于 2021-09-14T19:58:17.370 回答