cOM 指针

COM智能指针详解:CComPtr与_com_ptr_t的使用
本文详细介绍了COM智能指针的使用,包括ATL中的CComPtr和CComQIPtr,以及VC运行库中的_com_ptr_t。通过实例展示了如何创建、使用和管理COM接口,特别强调了生命周期管理和智能指针的正确使用方式,避免程序崩溃和内存泄漏问题。

最近在玩 MSHTML 和 MSXML,被一堆 COM 接口搞的晕头转向。

以前也玩过一些,但基本都是照抄别人的代码,也没注意到 IDispatch * 和 IDispatchPtr 有啥区别,就模糊的认为可能是同一个东东的两种写法罢……

这次趁机仔细研究了一番,转载3篇 COM 智能指针的详细的介绍,以备不时之需

 ATL智能指针类

ATL中包含的智能指针包括:CAutoPtr、CAutoPtrArray和CAutoPtrList, CComPtr和CComQIPtr

一、CAutoPtr、CAutoPtrArray和CAutoPtrList

CAutoPtr是普通智能指针类,CAutoPtrArray是智能指针数组,两者都在atlbase.h中声明;CAutoPtrList是智能指针列表,在atlcoll.h中声明。

二、CComPtr和CComQIPtr

CComPtr和CComQIPtr都是用来管理COM接口指针的类,CComQIPtr可完全取代CComPtr,两者的区别在于:CComQIPtr实现了运算符的重载功能,它可以自动调用QueryInterface()函数,CComQIPtr 唯一的缺点是不能定义 IUnknown * 指针。CComQIPtr<IUnknown > spUn是错误的。

1.声明和定义:

声明和定义一个CComQIPtr指针ISample。

CComQIPtr<ISample> spSample(IOtherInterface); 等价于

CComQIPtr<ISample> spSample =IOtherInterface;/*运算符重载*/  等价于

CComQIPtr<ISample> spSample;

IOtherInterface->QueryInterface(IID_ISample, &spSample);

2.函数调用:

智能指针调用函数分智能指针函数调用和智能指针内部接口指针函数调用,如上面声明的spSample,

spSample.CoCreateInstance(),spSample.QueryInterface等价于API函数调用::CoCreateInstance()和::QueryInterface();

spSample.QueryInterface()等价于内部接口指针函数spSample->QueryInterface()。

spSample->AddRef()正确,但spSample->Release()是错误的,因为它调用的是内部接口函数,并不能完全释放智能指针,而后还会再调用一次Release()释放指

COMComponent Object Model)中,通常使用引用计数来管理对象的生命周期。COM 对象要求实现 `IUnknown` 接口,并提供 `AddRef()` 和 `Release()` 方法来增加和减少引用计数。为了避免手动调用这些方法带来的错误和复杂性,C++ 提供了**智能指针**来自动管理 COM 对象的生命周期。 --- ### **一、COM 智能指针的作用** COM 智能指针的主要作用是: - 自动调用 `AddRef()` 和 `Release()`。 - 防止内存泄漏和悬空指针。 - 提高代码可读性和健壮性。 --- ### **二、常用的 COM 智能指针类型** #### 1. ATL 的 `CComPtr<T>` ATL(Active Template Library)提供的智能指针,常用于 Windows 平台开发。 ```cpp #include <atlbase.h> #include <atlcom.h> // 声明智能指针 CComPtr<IMyInterface> pMyObject; // 创建 COM 对象并赋值 HRESULT hr = CoCreateInstance(CLSID_MyClass, NULL, CLSCTX_INPROC_SERVER, IID_IMyInterface, (void**)&pMyObject); if (SUCCEEDED(hr)) { pMyObject->SomeMethod(); // 调用接口方法 } ``` 特点: - 自动调用 `AddRef()` 和 `Release()`。 - 支持赋值运算符重载。 - 可以通过 `pMyObject.p` 获取原始指针。 --- #### 2. WRL 的 `Microsoft::WRL::ComPtr<T>` Windows Runtime C++ Template Library 提供的智能指针,适用于 UWP 和 WinRT 开发。 ```cpp #include <wrl.h> using namespace Microsoft::WRL; ComPtr<IMyInterface> pMyObject; HRESULT hr = pMyObject.As<IMyInterface>(); if (SUCCEEDED(hr)) { pMyObject->SomeMethod(); } ``` 特点: - 更加现代和灵活。 - 支持模板化,适合通用开发。 - 与 WinRT 集成良好。 --- #### 3. 自定义智能指针(RAII) 如果不想依赖 ATL 或 WRL,可以自己实现一个简单的 COM 智能指针: ```cpp template <typename T> class ComPtr { public: ComPtr(T* p = nullptr) : ptr(p) { if (ptr) ptr->AddRef(); } ~ComPtr() { if (ptr) ptr->Release(); } T* operator->() const { return ptr; } T** operator&() { return &ptr; } private: T* ptr; }; ``` 使用示例: ```cpp ComPtr<IMyInterface> pMyObject; HRESULT hr = CoCreateInstance(CLSID_MyClass, NULL, CLSCTX_INPROC_SERVER, IID_IMyInterface, (void**)&pMyObject); ``` --- ### **三、注意事项** 1. **不要手动调用 AddRef/Release** - 使用智能指针后,应避免手动调用 `AddRef()` 和 `Release()`,否则会导致引用计数混乱。 2. **不能直接复制智能指针** - 如果需要传递 COM 指针,应使用 `CopyTo()` 或 `.Get()` 方法获取原始指针再赋值给另一个智能指针。 3. **线程安全问题** - COM 智能指针本身不保证线程安全,跨线程访问时需自行处理同步。 4. **避免裸指针智能指针混用** - 尽量避免将裸指针赋值给智能指针或反之,否则容易导致资源管理混乱。 --- ### **四、总结** | 类型 | 库 | 特点 | |------|----|------| | `CComPtr<T>` | ATL | 简单易用,广泛用于传统 COM 开发 | | `ComPtr<T>` | WRL | 现代风格,适合 WinRT/UWP 开发 | | 自定义 RAII | C++ 标准库 | 更加灵活,但需要自己实现 | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值