回答
MsiViewClose()
不需要关闭手柄。仅当您要运行时才需要
MsiViewExecute()
再次在同一视图上,这对于向参数化SQL查询传递不同的参数非常有用。这在
documentation
:
必须在msiviewExecute之前调用msiviewClose函数
在视图上再次调用函数,除非结果的所有行
已使用msiViewFetch函数获取集合。
在最常见的用例中,您只执行一个
msiView执行()
调用给定视图,不需要调用
msiView关闭()
:
PMSIHANDLE pView;
UINT res = MsiDatabaseOpenViewW( hDatabase, L"SELECT * FROM `File`", &pView );
if( res == ERROR_SUCCESS )
{
res = MsiViewExecute( pView, nullptr );
}
// Destructor of PMSIHANDLE calls MsiCloseHandle()
旁注
从现代C++的观点,
PMSIHANDLE
似乎设计得不好。首先,它不提供防止意外复制句柄的保护,这将导致调用
msiView关闭()
在同一个手柄上两次。同时将隐式转换为
MSIHANDLE*
可以很方便,也很危险,因为这样可以意外地覆盖现有的句柄,而不必先关闭它。
这里有一个替代
PMSIhandle公司
基于C++ 11S
std::unique_ptr
:
// A deleter for MSIHANDLE.
struct MsiHandleDeleter
{
// This alias enables us to actually store values of type MSIHANDLE in the unique_ptr
// (by default it would be MSIHANDLE*).
using pointer = MSIHANDLE;
void operator()( MSIHANDLE h ) const { if( h ) ::MsiCloseHandle( h ); }
};
// A RAII wrapper for MSI handle. The destructor automatically closes the handle, if not 0.
using UniqueMsiHandle = std::unique_ptr< MSIHANDLE, MsiHandleDeleter >;
用法示例:
UniqueMsiHandle record{ ::MsiCreateRecord( 1 ) };
::MsiRecordSetInteger( record.get(), 1, 42 );
// Destructor takes care of calling MsiCloseHandle(), just like PMSIHANDLE.
与…相比
PMSIhandle公司
将它与具有
msi句柄*
输出参数,但可以通过创建包装函数或使用
UnqiueMsiHandle
.
优势:
-
减少做错事情的方法。
-
清晰的所有权和
moveability
.
-
每个习惯的人
STD:UngQuyPPTR
将立即理解
UniqueMsiHandle
.