C++ 是否可以将所有权从空*转移到唯一的ptr?
我目前正在为一些插件项目使用C++ 是否可以将所有权从空*转移到唯一的ptr?,c++,c++11,C++,C++11,我目前正在为一些插件项目使用dlopen函数。 此函数句柄返回一个void*,然后我将所有句柄保存到名为handles的映射中: void* handle = dlopen(path.c_str(), RTLD_LAZY); handles[file] = handle; 我的目标是将所有权传递给地图,我正在考虑一个独特的\u ptr,但不确定这是否可行 如果不可能,我还有其他选择吗?如果我理解正确,你可以做类似的事情 为指针类型定义关闭函数和别名: auto closeFunc = []
dlopen
函数。此函数句柄返回一个
void*
,然后我将所有句柄保存到名为handles
的映射中:
void* handle = dlopen(path.c_str(), RTLD_LAZY);
handles[file] = handle;
我的目标是将所有权传递给地图,我正在考虑一个独特的\u ptr
,但不确定这是否可行
如果不可能,我还有其他选择吗?如果我理解正确,你可以做类似的事情 为指针类型定义关闭函数和别名:
auto closeFunc = [](void* vp) {
dlclose(vp);
};
using HandlePtr = std::unique_ptr<void, decltype(closeFunc)>;
std::map<std::string, HandlePtr> handles;
当唯一ptr超出范围时,将调用closeFunc
可以通过组合上面的两行来防止原始指针:
HandlePtr handle(dlopen(path.c_str(), RTLD_LAZY), closeFunc );
handles[file] = std::move( handle );
这将使用指定要使用的删除程序的第二个参数
ps:代码> map < /Calp> s和<代码> UNQuijpPTR s不能按原样播放,您可能需要一些使用或使用C++标准的移动或移动。或者使用
shared\u ptr
如果我理解正确的话,你可以这样做
为指针类型定义关闭函数和别名:
auto closeFunc = [](void* vp) {
dlclose(vp);
};
using HandlePtr = std::unique_ptr<void, decltype(closeFunc)>;
std::map<std::string, HandlePtr> handles;
当唯一ptr超出范围时,将调用closeFunc
可以通过组合上面的两行来防止原始指针:
HandlePtr handle(dlopen(path.c_str(), RTLD_LAZY), closeFunc );
handles[file] = std::move( handle );
这将使用指定要使用的删除程序的第二个参数
ps:代码> map < /Calp> s和<代码> UNQuijpPTR s不能按原样播放,您可能需要一些使用或使用C++标准的移动或移动。或者使用
shared\u ptr
std::unique_ptr对于“包装”使用资源而不需要在完成时删除或关闭的c库特别有用。它不仅可以防止您忘记何时删除/关闭资源,还可以使使用资源异常变得安全—因为在发生异常时,资源会得到正确的清理
我可能会这样做:
// closer function to clean up the resource
struct dl_closer{ void operator()(void* dl) const { dlclose(dl); }};
// type alias so you don't forget to include the closer functor
using unique_dl_ptr = std::unique_ptr<void, dl_closer>;
// helper function that ensures you get a valid dl handle
// or an exception.
unique_dl_ptr make_unique_dl(std::string const& file_name)
{
auto ptr = unique_dl_ptr(dlopen(file_name.c_str(), RTLD_LAZY));
if(!ptr)
throw std::runtime_error(dlerror());
return ptr;
}
// open a dl
auto dl_ptr = make_unique_dl("/path/to/my/plugin/library.so");
// now set your symbols using POSIX recommended casting gymnastics
void (*my_function_name)();
if(!(*(void**)&my_function_name = dlsym(dl_ptr.get(), "my_function_name")))
throw std::runtime_error(dlerror());
std::unique_ptr
对于“包装”使用资源而不需要在完成时删除或关闭的c库特别有用。它不仅可以防止您忘记何时删除/关闭资源,还可以使使用资源异常变得安全—因为在发生异常时,资源会得到正确的清理
我可能会这样做:
// closer function to clean up the resource
struct dl_closer{ void operator()(void* dl) const { dlclose(dl); }};
// type alias so you don't forget to include the closer functor
using unique_dl_ptr = std::unique_ptr<void, dl_closer>;
// helper function that ensures you get a valid dl handle
// or an exception.
unique_dl_ptr make_unique_dl(std::string const& file_name)
{
auto ptr = unique_dl_ptr(dlopen(file_name.c_str(), RTLD_LAZY));
if(!ptr)
throw std::runtime_error(dlerror());
return ptr;
}
// open a dl
auto dl_ptr = make_unique_dl("/path/to/my/plugin/library.so");
// now set your symbols using POSIX recommended casting gymnastics
void (*my_function_name)();
if(!(*(void**)&my_function_name = dlsym(dl_ptr.get(), "my_function_name")))
throw std::runtime_error(dlerror());
即使獾的答案是最好的遵循。请记住,C++中没有所有权概念,C++提供了类比来模拟并充分利用RAII,但是实际上,您没有从语言中保证任何一个源的所有权,即使是使用UNQuyQuPTR,例如:
{
auto p_i = new int{5};
auto up_i = std::unique_ptr<int>{p_i};
*p_i = 6; //nothing in the language prevent something like this
assert(*up_i == 6); //the unique_ptr ownership is not assured as you can see here
delete p_i; //still not illegal
} //at run time, RAII mechanism strikes, destroy unique_ptr, try to free an already freed memory, ending up to a core dumped
{
自动p_i=新整数{5};
auto-up_i=std::unique_ptr{p_i};
*p_i=6;//语言中没有任何东西可以阻止这样的事情
assert(*up_i==6);//正如您在这里看到的那样,无法确保唯一的\u ptr所有权
删除p_i;//仍然不是非法的
}//在运行时,RAII机制攻击,销毁unique_ptr,尝试释放已释放的内存,最终导致内核转储
您甚至在unique_ptr类中有一个get member函数,它让您有机会像处理原始指针一样扰乱内存
在C++中,没有一种机制可以在编译时检测到“所有权”违反,也许你可以找到一些工具去检查它,但是它不是标准的,但是这只是推荐的实践。
因此,在C++中讨论“托管”内存,而不是“所有权”更为贴切和精确。 < P>即使BADGER应答是最好的。请记住,C++中没有所有权概念,C++提供了类比来模拟并充分利用RAII,但是实际上,您没有从语言中保证任何一个源的所有权,即使是使用UNQuyQuPTR,例如:
{
auto p_i = new int{5};
auto up_i = std::unique_ptr<int>{p_i};
*p_i = 6; //nothing in the language prevent something like this
assert(*up_i == 6); //the unique_ptr ownership is not assured as you can see here
delete p_i; //still not illegal
} //at run time, RAII mechanism strikes, destroy unique_ptr, try to free an already freed memory, ending up to a core dumped
{
自动p_i=新整数{5};
auto-up_i=std::unique_ptr{p_i};
*p_i=6;//语言中没有任何东西可以阻止这样的事情
assert(*up_i==6);//正如您在这里看到的那样,无法确保唯一的\u ptr所有权
删除p_i;//仍然不是非法的
}//在运行时,RAII机制攻击,销毁unique_ptr,尝试释放已释放的内存,最终导致内核转储
您甚至在unique_ptr类中有一个get member函数,它让您有机会像处理原始指针一样扰乱内存
在C++中,没有一种机制可以在编译时检测到“所有权”违反,也许你可以找到一些工具去检查它,但是它不是标准的,但是这只是推荐的实践。
这样,在C++中讨论“托管”内存而不是“所有权”更为贴切和精确。
<代码> VUL> */COD>本身没有所有权概念,原始指针所知道的唯一“所有权”是您应该删除它。如果你没有,那么指针不拥有任何可能的复制品,所有权在这里的确切含义是什么?看,当你完成手柄(如果有的话)时,你应该做什么清理?手柄需要关闭。因此,在清除映射时,我希望自动关闭所有句柄(比如在唯一的\u ptr deleter中)。目前,我必须手动调用“close”并进行擦除,因此有两个操作。我不确定,但这可能是一种简化的实现方法。从来没用过。其他人可以回答。void*
本身没有所有权的概念,原始指针知道的唯一“所有权”是你应该删除它,如果你不知道,那么指针就不拥有任何可能的副本,所有权在这里到底意味着什么?看,当你完成手柄(如果有的话)时,你应该做什么清理?手柄需要关闭。因此,在清除映射时,我希望自动关闭所有句柄(比如在唯一的\u ptr deleter中)。现在我得打电话给“亲密”人