c – 使用shared_ptr与自定义删除器进行HANDLE RAII兼容
我最近在
SO发布了关于RAII的一般问题.
但是,我的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 post SharedHandle 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 only class 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; }; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |