By Michael Dunn
From www.codeproject.com
/**********原创翻译,转载请注明出处*********** 新手水平有限,欢迎批评指教 By FreeKid /
COM入门简介 -- 什么是COM , 怎样使用它 (3)
删除COM对象
按照前文所说的,你不用去释放COM对象,需要做的仅仅是告诉它们你使用完了。每个COM对象实现的IUnknown接口都有一个Release()方法。你应该调用这个方法通知COM对象你不再需要它了。一旦调用了Release(),COM对象就从内存中消失,因此也就不能再使用接口指针了。
如果你的应用程序使用许多不同的COM对象,那么当你使用完接口之后调用Release()就显得极为重要。如果你不释放(release)接口,COM对象(还有包括代码的那些DLLs)将被保存在内存中,并且毫无必要的加入到你的应用程序中。如果应用程序要运行很长一段时间,在程序闲时,你应该调用CoFreeUnusedLibraries()函数。这个函数将卸载没有显著作用的COM服务器,这也能减少应用程序的内存使用量。
继续上面的示例,下面展示应该如何使用Release():
if ( SUCCEEDED ( hr ) )
... {
// Call methods using pISL here.
// Tell the COM object that we're done with it.
pISL->Release();
}
IUnknown接口将在下一部分详细说明。
基本接口 - IUnknown
每个COM接口都是从IUnknown继承而来。这个名字有点容易让人误解,因为实际它并不是一个未知(unknown)接口。这个名字意味着即使你有了一个指向COM对象的IUnknown指针,你也不会知道它下面的对象是什么,因为每个COM对象都实现了IUnknown。
IUnknown 有三个方法:
1. AddRef() - 告知COM对象增加它的引用计数。如果你拷贝了一个接口指针,你就需要使用这个方法,无论原始指针还是拷贝的副本都需要使用。在本文中,我们不必使用AddRef()方法。
2. Release() - 告知COM对象减少它的引用计数。你可以从前面的代码片段中找到关于Release()的说明。
3. QueryInterface() - 从COM对象中获取一个接口指针。当COClass实现二个或二个以上接口的时候,需要使用这个方法。
我们已经了解Release()是怎样运作的,那么QueryInterface()又是怎样的呢?当你用CoCreateInstance()创建一个COM对象的时候,你将得到一个接口指针。如果COM对象实现了二个或二个以上的接口(不包括IUnknown),你可以使用QueryInterface()来获取任意你想要的额外指针。QueryInterface()的原型如下:
REFIID iid,
void ** ppv );
参数如下:
iid
所请求接口的IID
ppv
接口指针的地址。如果调用成功,QueryInterface()则通过这个参数返回接口。
让我们继续那个快捷方式的的示例。生成快捷方式的COClass实现了IShellLink和IPersistFile接口。如果你已经有个一个IShellLink指针pISL,那面你可以像下面一样来从COM对象中获取IPersistFIle接口:
IPersistFile * pIPF;
hr = pISL -> QueryInterface ( IID_IPersistFile, ( void ** ) & pIPF );
之后你可以用SUCCEEDED宏测试hr,然后证明QueryInterface()是否成功运行了。如果成功,你就可以像使用其它接口一样使用新的接口指针pIPF了。当然,在你使用完毕后,一定要调用pIPF->Release()。
(未完待续)