gpt4 book ai didi

c++ - 通过采用 void * 的 C 接口(interface)传递 shared_ptr

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:16:01 24 4
gpt4 key购买 nike

我有一个使用 SDL 的 C++ 项目,特别是 SDL 事件。我想将事件系统用于传入的网络消息,就像它用于 UI 事件一样。我可以定义一个新的事件类型并附加一些任意数据(参见 this example )。如果我使用普通指针,这就是我会做的:

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_ptr,其中任何一个都可以删除消息对象,而其中一个仍在使用它。我需要以某种方式通过 SDL_UserEvent 结构传递 shared_ptr,它只有几个 void *和 int 字段。

附加。请注意 SDL_PostEvent立即返回;事件本身被放入队列中。在消息的 shared_ptr 超出网络代码的范围后,处理程序可能会从队列中弹出事件。所以我不能传递本地 shared_ptr 的地址来复制。到复制发生时,它可能不再有效。

有没有人遇到过类似的问题并且知道好的解决方案?

最佳答案

使用new 分配指向共享指针的指针。这会调用构造函数(增加引用计数),但不会调用相应的析构函数,因此 shared_ptr 永远不会破坏它的共享内存。

然后在相应的处理程序中,在复制 shared_ptr 后销毁对象,使其引用计数恢复正常。

这与您通过消息队列传递任何其他非原始类型的方式相同。

typedef shared_ptr<Message> MessagePtr;

Uint32 message_event_type = SDL_RegisterEvents(1);

/* In the main event loop */
while (SDL_Poll(&evt)) {
if (evt.type == message_event_type) {
// Might need to cast data1 to (shared_ptr<Message> *)
unique_ptr<MessagePtr> data (evt.user.data1);
MessagePtr msg = *data;
handle_message(msg);
}
}

/* Networking code, possibly in another thread */
MessagePtr msg = read_message_from_network();
SDL_Event evt;
evt.type = message_event_type;
evt.user.data1 = new MessagePtr (msg);
SDL_PostEvent(evt);

Messages are read-only objects once constructed

我只想指出,这对多线程安全来说是好的,甚至是必要的。你可能想使用 shared_ptr<const Message>

关于c++ - 通过采用 void * 的 C 接口(interface)传递 shared_ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31063055/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com