例:
typedef _com_ptr__t
IWorkspaceFactory p; |
|
//不能实例化抽象类 |
IWorkspaceFactoryPtr ipWorkSpaceFactory; |
|
//正确 |
先来看简单的,_uuidof
MSDN上的解释是:
The __uuidof keyword retrieves the GUID attached tothe expression. The expression can be a type name, a pointer, reference, orarray of that type, a template specialized on these types, or a variable ofthese types. The argument is valid as long as the compiler can use it to findthe attached GUID.
简单的说,__uuidof这个关键字的作用就是得到GUID的。
再看_com_ptr__t
A _com_ptr_t object encapsulates a COM interfacepointer and is called a “smart” pointer. This template class manages resourceallocation and deallocation, via function calls to theIUnknown member functions: QueryInterface,AddRef, and Release.
_com_ptr_t封装了一个COM的智能指针,这个模板类通过调用IUnknown 接口中函数( QueryInterface,AddRef, andRelease.)来实现分配和释放资源。
A smart pointer isusually referenced by the typedef definition provided by the_COM_SMARTPTR_TYPEDEF macro. This macro takesan interface name and the IID, and declares a specialization of_com_ptr_t with the name of the interface plusa suffix ofPtr.
这个智能指针通常由_COM_SMARTPTR_TYPEDEF 宏重定义,进行重定义时需要接口名称以及其IID做为参数。通常重定义后的名字为接口名加上Ptr后缀,及之后则可以使用形如“接口名称+Ptr”这样的名称来定义此种接口类型的智能指针。
通过智能指针,我们创建一个COM对象的方法简化为:
IWorkspaceFactoryPtripWorkSpaceFactory;
ipWorkSpaceFactory.CreateInstance(CLSID_ShapefileWorkspaceFactory); //创建读取shp文件的工作厂对象
不用再使用CoCreateInstance()函数。
使用*Ptr后QueryInterface的使用会简化,首先我们先看一下基本的QueryInterface基本使用:
voidfoo(IUnknown *PI)
{
IX*pIX=NULL;
HRESULThr=PI->QueryInterface(IID_IX,(void**)&pIX);
if(FAILED(hr))
return;
pIX->Fx();
}
其过程概括为,用一个以实例化的接口指针调用QueryInterface()得到新接口,再用请求到的新接口调用新接口中的方法。其中:
HRESULTQueryInterface(
REFIID iid, //Identifier of the requested interface 待请求接口的IID
void ** ppvObject //Address of outputvariable that receives the interface pointer requested in iid
存放所请求接口指针的地址
);
关于QueryInterface的实现原理可以参照:
http://www.cnblogs.com/fangyukuan/archive/2010/06/02/1750377.html
下面对比下两种不同的“QueryInterface()”方法
IFeatureClassPtrCWsClass::paGetFeatureClass(BSTR workspacePath,BSTR fileName)
{
CComPtr
ipWorksapceFactory.CoCreateInstance(CLSID_ShapefileWorkspaceFactory);
IWorkspace*m_workspace;
ipWorksapceFactory->OpenFromFile(workspacePath,NULL,&m_workspace);
IFeatureClassPtripFeatureClass;
if(m_workspace!=NULL)
{
//IFeatureWorkspacePtripFeatureWorkspace(m_workspace); //QI
IFeatureWorkspace*ipFeatureWorkspace;
m_workspace->QueryInterface(_uuidof(IFeatureWorkspace),(void**)&ipFeatureWorkspace);
HRESULThr=ipFeatureWorkspace->OpenFeatureClass(fileName,&ipFeatureClass);
if(FAILED(hr))
returnNULL;
}
returnipFeatureClass;
}
红色的两个部分都实现了QueryInterface过程,可以自行对照两者的异同。
稍后继续分析*Ptr与CComPtr两种智能指针的异同。