gpt4 book ai didi

c++ - 在回调中将 shared_ptr 转换为 void*

转载 作者:太空宇宙 更新时间:2023-11-04 11:49:26 26 4
gpt4 key购买 nike

我想在接受 void* 的 C 函数中传递一个 shared_ptr。 shared_ptr 中创建的对象被销毁是否安全,何时可以销毁?喜欢,

class CBar
{
public:
CBar(){}
~CBar(){}
void lock(){}
void unlock(){}
};

//----------------------------------------------------

typedef struct element
{
std::string filename;
void (*cb)(std::string filename, void* data);
void* data;
};

std::list<element> elm;

void reg(std::string filename, void (*cb)(std::string filename, void*data), void* data)
{
element item;
item.filename = filename;
item.cb = cb;
item.data = data;
}

void unreg(std::string filename)
{
std::list<elements>::iter;
for(iter=elm.begin();iter!=elm.end();++iter)
{
if((*iter).filename == filename)
{
elm.erase(iter);
break;
}
}
}

void exec()
{
std::list<element>::iterator iter;
for(iter=elm.begin();iter!=elm.end();++iter)
{
(*iter).cb((*iter).filename,(*iter).data);
}
}

//---------------------------------------------------
// in another source file

void cb(std::string filename, void* data)
{
boost::shared_ptr<CBar> cbar = *(boost::shared_ptr<CBar>*)(data);
cbar->lock();
}

void foo(std::string filename)
{
//create the shared_ptr here.
boost::shared_ptr<CBar> ffoo(new CBar);

//then pass the shared_ptr object
reg(filename, &cb, &ffoo);

}

int main()
{
foo("file");
exec();

return 0;
}

最佳答案

当您的函数离开作用域时,共享指针将被销毁。如果它是最后一个包装该数据的包装,则数据也随之包装(因此列表中的存储也变得虚假)。您的示例更加糟糕,因为您发送的是局部变量的地址,这在 reg() 的那一刻将是完全未定义的行为。函数退出,局部变量超出作用域

我建议您在元素 结构中也放置一个共享指针。毕竟,它是共享的,因此它将延长该数据的生命周期,直到元素被删除。如果这是一个真正的 C 类型回调,您可能还希望将第一个回调参数设置为 const char*。并发送 c_str()相应的方法。

注意:我没有安装 boost,所以下面的代码使用 std::shared_ptr<> , 但语义应该是一样的。

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <memory>
#include <cstdlib>

class CBar
{
public:
CBar(){}
~CBar(){}
void lock(){}
void unlock(){}
};

struct element
{
std::string filename;
void (*cb)(std::string, void* data);
std::shared_ptr<CBar> data;
};


std::list<element> elm;

void reg(std::string filename,
void (*cb)(std::string, void*),
std::shared_ptr<CBar>& data)
{
element item;
item.filename = filename;
item.cb = cb;
item.data = data;
elm.push_back(item);
}

void exec()
{
std::list<element>::iterator iter;
for(iter=elm.begin();iter!=elm.end();++iter)
{
iter->cb(iter->filename, iter->data.get());
}
}

// in another source file
void cb(std::string filename, void* data)
{
CBar *cbar = static_cast<CBar*>(data);
cbar->lock();
}

void foo(std::string filename)
{
//create the shared_ptr here.
std::shared_ptr<CBar> ffoo(new CBar);

//then pass the shared_ptr object
reg(filename, &cb, ffoo);

}

int main()
{
foo("file");
exec();
return 0;
}

关于c++ - 在回调中将 shared_ptr 转换为 void*,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18930613/

26 4 0
文章推荐: java - Scala 使用数组参数调用 Java 方法
文章推荐: HTML 布局(基本)- CSS 问题
文章推荐: html -
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com