但是,我的HANDLE示例仍然有一些实现问题.
在windows.h中,一个HANDLE被打破为voID *.因此,需要正确的shared_ptr定义
std::tr1::shared_ptr<voID> myHandle (INVALID_HANDLE_VALUE,CloseHandle);
示例1 Createtoolhelp32Snapshot:返回HANDLE并工作.
const std::tr1::shared_ptr<voID> h (Createtoolhelp32Snapshot(TH32CS_SNAPPROCESS,NulL),CloseHandle);
当我在定义中使用voID(什么是正确的方式?)问题继续,当我尝试使用这个指针调用一些更多的winAPI命令.他们在功能上工作,但是很丑,我确信必须有更好的解决方案.
在以下示例中,h是通过顶部定义创建的指针.
示例2 OpenProcesstoken:最后一个参数是PHANDLE.中等丑与演员.
OpenProcesstoken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_query,(PHANDLE)&h);
示例3 Process32First:第一个参数是一个HANDLE.真的很丑
Process32First(*((PHANDLE)&h),&pEntry);
示例4简单的比较一个恒定的HANDLE.真的很丑
if (*((PHANDLE)&h) == INVALID_HANDLE) { /* do something */ }
为HANDLE创建适当的shared_ptr的正确方法是什么?
解决方法 示例1可以示例2是错误的.通过盲目投射到PHANDLE,shared_ptr逻辑被绕过.它应该是这样的:
HANDLE h;OpenProcesstoken(....,&h);shared_ptr<voID> safe_h(h,&::CloseHandle);
或者分配给一个pre-exising shared_ptr:
shared_ptr<voID> safe_h = ....{ HANDLE h; OpenProcesstoken(....,&h); safe_h.reset(h,&::CloseHandle);}//For extra safety,limit visibility of the naked handle
或创建自己的安全版本的OpenProcesstoken,返回一个共享句柄,而不是使用PHANDLE:
// Using SharedHandle defined at the end of this postSharedHandle OpenProcess(....){ HANDLE h = INVALID_HANDLE_VALUE; ::OpenProcesstoken(....,&h); return SharedHandle(h);}
示例3:不需要走这些弯路.这应该是可以的
Process32First(h.get(),...);
示例4:再次,没有绕道:
if (h.get() == INVALID_HANDLE){...}
为了使事情更美好,你可以打字像:
typedef shared_ptr<voID> SharedHandle;
或者更好的是,如果要使用CloseHandle()关闭所有句柄,请创建一个包装shared_ptr并自动提供正确的删除器的SharedHandle类:
// Warning: Not tested. For illustration purposes onlyclass SharedHandle{public: explicit SharedHandle(HANDLE h) : m_Handle(h,&::CloseHandle){}; HANDLE get()const{return m_Handle.get();} //Expose other shared_ptr-like methods as needed //...private: shared_ptr<voID> m_Handle;};总结
以上是内存溢出为你收集整理的c – 使用shared_ptr与自定义删除器进行HANDLE RAII兼容全部内容,希望文章能够帮你解决c – 使用shared_ptr与自定义删除器进行HANDLE RAII兼容所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)