Вам не нужно ничего пропускать. Просто используйте поле userData
структуры ENetPacket
, чтобы сохранить подлежащее удалению std::vector
, и просто удалите его в обратном вызове:
void myCallback(ENetPacket *pkt) {
std::vector<uint8_t> *data=(std::vector<uint8_t> *)pkt->userData;
delete data;
}
void sendData() {
//Create the vector in heap, so it is not destroyed after returning from this function, effectively extending its life until the callback is called.
std::vector<uint8_t> *data=new std::vector<uint8_t>;
//Fill data here
ENetPacket *pkt=enet_packet_create(data.data(), data.size(), ENET_PACKET_FLAG_NO_ALLOCATE);
pkt->userData=(void*)data;
pkt->freeCallback=myCallback;
}
userData
void указатель - это обычная стратегия для хранения непрозрачных пользовательских данных и использования их в обратных вызовах, поэтому пользователь библиотеки может получить контекст, в котором был вызван обратный вызов.
Это может быть что угодно (void*
), из структуры держателей состояний для выполнения сложной логики после обратного вызова, или просто указатель данных, который должен быть освобожден, как ваш случай.
Из ваших комментариев вы говорите, что выне хочу динамически выделять vector
.
Просто помните, что любые данные внутри вектора были динамически распределены (если не был использован пользовательский распределитель), и структура ENetPacket
также была динамически распределена(переданный флаг просто указывает, что не следует выделять data
, а не структуру)
Наконец, если вы знаете (или можете предварительно вычислить) размер данных, другой подходможет быть для создания пакета, передающего нулевой указатель данных.
Функция enet_packet_create
создаст буфер данных, и вы можете просто заполнить данные непосредственно в буфере пакетов, не требуя другого буфера, а затем скопировать его в пакет.