理解接口开发中的*Ptr

来源:互联网 发布:原谅我红尘颠倒 知乎 编辑:程序博客网 时间:2024/06/06 18:48

例:

typedef _com_ptr__t<com_IIID<IWorkspaceFactory,&_uuidof(IWorksapceFactory)>>IWorkspaceFactoryPtr

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, andRelease.

_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<IWorkspaceFactory>ipWorksapceFactory;

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过程,可以自行对照两者的异同。

稍后继续分析*PtrCComPtr两种智能指针的异同。

0 0
原创粉丝点击