谁会用COM的智能指针吗,请来接分. 我没用过智能指针,比如我在一个组件里定义了一个方法Add(long l1,long l2, long*p);用它来把两个数相加并返回结果.现在我要在客户端程序中调用这个方法,怎么做呢? 网上没找到例子,可能问题太简单吧.你能给我写个例子吗? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 跟智能指针没关系吗?我看一个教程说,调用COM组件的三种方法是...前面两种我已经掌握了,就第三种,说要#import".."..然后用智能指针... 就这第三种不懂呀 伪代码:CoCreateInstance();QueryInterface(IID_ADD,(void**)&pAdd);pAdd->Add();pAdd->Release()// 如果用智能指针就不用手动进行Release了. 智能指针是对com接口的封装。重载了->操作符,而且会在析构中调用接口的release.假如你有一个智能指针。给个乱写的例子:_ComInterfacePtr InterfacePtrObj;InterfacePtrObj.CreateInstace(__uuidof(ComInterface));//可能需要。InterfacePtrObj->ComInterface_Fun();就这样调用. 你所说的, 第三种,说要#import"..".., 是这个样子的: 用#import 导入1类型库文件, 在你工程里回有一个这样的文件生成*.tlh, 在这个文件里面会有这样的语句: _COM_SMARTPTR_TYPEDEF(IXXXX, __uuidof(IXXXX));而 _COM_SMARTPTR_TYPEDEF 宏展开后: #define _COM_SMARTPTR_TYPEDEF(Interface, IID) \ typedef _COM_SMARTPTR<Interface, &IID> \ Interface ## Ptr其中 #define _COM_SMARTPTR _com_ptr_t_com_ptr_t 就是所谓的智能指针(模板类), 可以帮助你管理接口的引用记数.可以看到他的源代码: vc98\include\COMIP.h 其实真正的目的就是: typedef _com_ptr_t<Interface, &IID> interface ## Ptr;假如你的COM对象实现的接口是 ISelfInterface, 那么就是: typedef _com_ptr_t<ISelfInterface, __uuidof(ISelfInterface> ISelfInterfacePtr;这样就十分明显了用#import导入类型库, 在*.tlh文件中帮你定义了一个新的类型, 如上例所示就是 ISelfInterfacePtr(接口智能指针类型) , 所以就可以用这个类型来声明接口了.可用的方法都在_com_ptr_t中. 呵呵, 我觉的我说的已经非常清楚了. 补充一下: 在使用的时候就可以: IselfInterfacePtr spSelfInterface; // 声明接口指针. m_spObj.CreateInstance(给定CLSID); // 就可以创建COM对象, 得到ISelfInterface接口的 指针了 你问的问题好像和智能指针没多大关系智能指针就有点像类的模板看看下面的模板你就知道了:template <class T>class CComPtr{public: typedef T _PtrClass; CComPtr() { p=NULL; } CComPtr(T* lp) { if ((p = lp) != NULL) p->AddRef(); } CComPtr(const CComPtr<T>& lp) { if ((p = lp.p) != NULL) p->AddRef(); } ~CComPtr() { if (p) p->Release(); } void Release() { IUnknown* pTemp = p; if (pTemp) { p = NULL; pTemp->Release(); } } operator T*() const { return (T*)p; } T& operator*() const { ATLASSERT(p!=NULL); return *p; } //The assert on operator& usually indicates a bug. If this is really //what is needed, however, take the address of the p member explicitly. T** operator&() { ATLASSERT(p==NULL); return &p; } _NoAddRefReleaseOnCComPtr<T>* operator->() const { ATLASSERT(p!=NULL); return (_NoAddRefReleaseOnCComPtr<T>*)p; } T* operator=(T* lp) { return (T*)AtlComPtrAssign((IUnknown**)&p, lp); } T* operator=(const CComPtr<T>& lp) { return (T*)AtlComPtrAssign((IUnknown**)&p, lp.p); } bool operator!() const { return (p == NULL); } bool operator<(T* pT) const { return p < pT; } bool operator==(T* pT) const { return p == pT; } // Compare two objects for equivalence bool IsEqualObject(IUnknown* pOther) { if (p == NULL && pOther == NULL) return true; // They are both NULL objects if (p == NULL || pOther == NULL) return false; // One is NULL the other is not CComPtr<IUnknown> punk1; CComPtr<IUnknown> punk2; p->QueryInterface(IID_IUnknown, (void**)&punk1); pOther->QueryInterface(IID_IUnknown, (void**)&punk2); return punk1 == punk2; } void Attach(T* p2) { if (p) p->Release(); p = p2; } T* Detach() { T* pt = p; p = NULL; return pt; } HRESULT CopyTo(T** ppT) { ATLASSERT(ppT != NULL); if (ppT == NULL) return E_POINTER; *ppT = p; if (p) p->AddRef(); return S_OK; } HRESULT SetSite(IUnknown* punkParent) { return AtlSetChildSite(p, punkParent); } HRESULT Advise(IUnknown* pUnk, const IID& iid, LPDWORD pdw) { return AtlAdvise(p, pUnk, iid, pdw); } HRESULT CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) { ATLASSERT(p == NULL); return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p); } HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) { CLSID clsid; HRESULT hr = CLSIDFromProgID(szProgID, &clsid); ATLASSERT(p == NULL); if (SUCCEEDED(hr)) hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p); return hr; } template <class Q> HRESULT QueryInterface(Q** pp) const { ATLASSERT(pp != NULL && *pp == NULL); return p->QueryInterface(__uuidof(Q), (void**)pp); } T* p;}; 使用智能指针可以简化一些操作,像指针的释放,就不用手去再去release了,它的析构函数就有了这个操作另外它重载了一些操作像"=""*"等使指针的操作变得很方便 一个SOCKET得程序,客户端发送出数据,而服务端接收不到? 如何终止系统进程 如何在命令行下编译VC工程? 单击某个按纽,如何获得这个按纽的句柄? 急,在ListCtrl的report风格下,能不能把图片和文字放到同一个Item中 很弱的问题, 关于全局变量 请教倾斜椭圆的方法 BoundsChecker and Visual C++6 有报酬,请大侠来看一下 vc中如何扑捉键盘 toolbar上按钮想改变背景和文字颜色,如何做。 关于QQ游戏大厅的游戏列表的问题
我看一个教程说,调用COM组件的三种方法是...前面两种我已经掌握了,就第三种,说要#import".."..
然后用智能指针... 就这第三种不懂呀
QueryInterface(IID_ADD,(void**)&pAdd);
pAdd->Add();
pAdd->Release()// 如果用智能指针就不用手动进行Release了.
假如你有一个智能指针。
给个乱写的例子:
_ComInterfacePtr InterfacePtrObj;
InterfacePtrObj.CreateInstace(__uuidof(ComInterface));//可能需要。
InterfacePtrObj->ComInterface_Fun();就这样调用.
用#import 导入1类型库文件, 在你工程里回有一个这样的文件生成*.tlh, 在这个文件里面会有这样的语句:
_COM_SMARTPTR_TYPEDEF(IXXXX, __uuidof(IXXXX));而 _COM_SMARTPTR_TYPEDEF 宏展开后:
#define _COM_SMARTPTR_TYPEDEF(Interface, IID) \
typedef _COM_SMARTPTR<Interface, &IID> \
Interface ## Ptr其中 #define _COM_SMARTPTR _com_ptr_t
_com_ptr_t 就是所谓的智能指针(模板类), 可以帮助你管理接口的引用记数.可以看到他的源代码: vc98\include\COMIP.h 其实真正的目的就是: typedef _com_ptr_t<Interface, &IID> interface ## Ptr;
假如你的COM对象实现的接口是 ISelfInterface, 那么就是:
typedef _com_ptr_t<ISelfInterface, __uuidof(ISelfInterface> ISelfInterfacePtr;
这样就十分明显了用#import导入类型库, 在*.tlh文件中帮你定义了一个新的类型, 如上例所示就是 ISelfInterfacePtr(接口智能指针类型) , 所以就可以用这个类型来声明接口了.可用的方法都在_com_ptr_t中. 呵呵, 我觉的我说的已经非常清楚了.
在使用的时候就可以: IselfInterfacePtr spSelfInterface; // 声明接口指针.
m_spObj.CreateInstance(给定CLSID); // 就可以创建COM对象, 得到ISelfInterface接口的 指针了
智能指针就有点像类的模板
看看下面的模板你就知道了:
template <class T>
class CComPtr
{
public:
typedef T _PtrClass;
CComPtr()
{
p=NULL;
}
CComPtr(T* lp)
{
if ((p = lp) != NULL)
p->AddRef();
}
CComPtr(const CComPtr<T>& lp)
{
if ((p = lp.p) != NULL)
p->AddRef();
}
~CComPtr()
{
if (p)
p->Release();
}
void Release()
{
IUnknown* pTemp = p;
if (pTemp)
{
p = NULL;
pTemp->Release();
}
}
operator T*() const
{
return (T*)p;
}
T& operator*() const
{
ATLASSERT(p!=NULL);
return *p;
}
//The assert on operator& usually indicates a bug. If this is really
//what is needed, however, take the address of the p member explicitly.
T** operator&()
{
ATLASSERT(p==NULL);
return &p;
}
_NoAddRefReleaseOnCComPtr<T>* operator->() const
{
ATLASSERT(p!=NULL);
return (_NoAddRefReleaseOnCComPtr<T>*)p;
}
T* operator=(T* lp)
{
return (T*)AtlComPtrAssign((IUnknown**)&p, lp);
}
T* operator=(const CComPtr<T>& lp)
{
return (T*)AtlComPtrAssign((IUnknown**)&p, lp.p);
}
bool operator!() const
{
return (p == NULL);
}
bool operator<(T* pT) const
{
return p < pT;
}
bool operator==(T* pT) const
{
return p == pT;
}
// Compare two objects for equivalence
bool IsEqualObject(IUnknown* pOther)
{
if (p == NULL && pOther == NULL)
return true; // They are both NULL objects if (p == NULL || pOther == NULL)
return false; // One is NULL the other is not CComPtr<IUnknown> punk1;
CComPtr<IUnknown> punk2;
p->QueryInterface(IID_IUnknown, (void**)&punk1);
pOther->QueryInterface(IID_IUnknown, (void**)&punk2);
return punk1 == punk2;
}
void Attach(T* p2)
{
if (p)
p->Release();
p = p2;
}
T* Detach()
{
T* pt = p;
p = NULL;
return pt;
}
HRESULT CopyTo(T** ppT)
{
ATLASSERT(ppT != NULL);
if (ppT == NULL)
return E_POINTER;
*ppT = p;
if (p)
p->AddRef();
return S_OK;
}
HRESULT SetSite(IUnknown* punkParent)
{
return AtlSetChildSite(p, punkParent);
}
HRESULT Advise(IUnknown* pUnk, const IID& iid, LPDWORD pdw)
{
return AtlAdvise(p, pUnk, iid, pdw);
}
HRESULT CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
{
ATLASSERT(p == NULL);
return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);
}
HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
{
CLSID clsid;
HRESULT hr = CLSIDFromProgID(szProgID, &clsid);
ATLASSERT(p == NULL);
if (SUCCEEDED(hr))
hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);
return hr;
}
template <class Q>
HRESULT QueryInterface(Q** pp) const
{
ATLASSERT(pp != NULL && *pp == NULL);
return p->QueryInterface(__uuidof(Q), (void**)pp);
}
T* p;
};
另外它重载了一些操作像"=""*"等使指针的操作变得很方便