我有一个使用SDL的C++项目,特别是SDL事件。我想像UI事件一样使用事件系统来处理传入的网络消息。我可以定义一个新的事件类型并附加一些任意数据(请参见this example)。如果我使用普通指针,这就是我要做的事情:
然后有两个独立的shared_ptrs,任何一个都可以在另一个仍在使用它时删除Message对象。我需要以某种方式通过SDL_UserEvent结构传递shared_ptr,该结构仅具有几个void *和int字段。
此外,请注意,SDL_PostEvent立即返回;事件本身被放入队列中。处理程序可能会在网络代码中的shared_ptr已经超出范围之后很久才从队列中弹出事件。因此,我不能传递局部shared_ptr的地址进行复制。当复制发生时,它很可能不再有效。
有没有人遇到过类似的问题并知道一个好的解决方案?
Uint32 message_event_type = SDL_RegisterEvents(1);
/* In the main event loop */
while (SDL_Poll(&evt)) {
if (evt.type == message_event_type) {
Message *msg = evt.user.data1;
handle_message(msg);
}
}
/* Networking code, possibly in another thread */
Message *msg = read_message_from_network();
SDL_Event evt;
evt.type = message_event_type;
evt.user.data1 = msg;
SDL_PostEvent(evt);
目前我一直在使用shared_ptr<Message>
。消息对象在构建后是只读的,而且在处理过程中可能被用于许多地方,所以我认为使用shared_ptr比较合适。
我想在网络端和事件处理端都使用一个指向该消息的shared_ptr。如果我这样做:
// in networking code:
shared_ptr<Message> msg = ...
evt.user.data1 = msg.get();
// later, in event handling:
shared_ptr<Message> msg(evt.user.data1);
然后有两个独立的shared_ptrs,任何一个都可以在另一个仍在使用它时删除Message对象。我需要以某种方式通过SDL_UserEvent结构传递shared_ptr,该结构仅具有几个void *和int字段。
此外,请注意,SDL_PostEvent立即返回;事件本身被放入队列中。处理程序可能会在网络代码中的shared_ptr已经超出范围之后很久才从队列中弹出事件。因此,我不能传递局部shared_ptr的地址进行复制。当复制发生时,它很可能不再有效。
有没有人遇到过类似的问题并知道一个好的解决方案?
shared_ptr
的指针传递,并在接收函数中进行值复制。例如:evt.user.data1 = &msg;
和shared_ptr<Message> msg = *reinterpret_cast<shared_ptr<Message>*>(evt.user.data1);
。 - Jonathan Pottershared_ptr
(尽管如果可以手动增加引用计数,如@EyasSH在下面建议的那样,则shared_from_this
可能是一个选项)。 - Jonathan Potter