COM编程入门,十分浅显易懂
4. 如果确实实现勒索请求的接口,则增加COM对象的引用计数。
[((IUnknown*) *ppv)->AddRef();]
AddRef()调用很关键。
*ppv = (IUnknown*) this;
要创建新的COM对象引用,就必须调用这个函数通知COM对象这个新引用成立。在AddRef()调用中的强制转换IUnknown*看起来好像多余,但是在QI()中初始化的*ppv有可能不是IUnknown*类型,所以最好是养成习惯对之进行强行转换。。
上面我们已经讨论了一些DLL服务器的内部细节,接下来让我们回头看一看当客户端调用CoCreateInstance()时是如何处理服务器的。
深入CoCreateInstance()
在本文的第一部分中,我们见过CoCreateInstance()API,其作用是当客户端请求对象时,用它来创建对象。从客户端的立场 看,它是一个黑盒子。只要用正确的参数调用它即可得到一个COM对象。它并没有什么魔法,只是在一个定义良好的过程中加载COM服务器,创建请求的COM 对象并返回所要的指针。就这些。
下面让我们来浏览一下这个过程。这里要涉及到几个不太熟悉的术语,但不用着急,后面会对它们作详细讨论。
1. 客户端程序调用CoCreateInstance(),传递组件对象类的CLSID以及所要接口的IID;
2. COM库在HKEY_CLASSES_ROOT\CLSID.键值下查找服务器的CLSID键值,这个键值包含服务器的注册信息;
3. COM库读取服务器DLL的全路径并将DLL加载到客户端的进程空间;
4. COM库调用在服务器中DllGetClassObject()函数为所请求的组件对象类请求类工厂;
5. 服务器创建一个类工厂并将它从DllGetClassObject()返回;
6. COM库在类工厂中调用CreateInstance()方法创建客户端程序请求的COM对象;
7. CreateInstance()返回一个接口指针到客户端程序;
COM服务器注册
COM 服务器必须在 Windows 注册表中正确注册以后才能正常工作。如果你看一下注册表中的 HKEY_CLASSES_ROOT\CLSID 键,就会发现大把大把子键,它们就是在这个计算机上注册的COM服务器。当某个COM服务器注册后(通常是用DllRegisterServer()进行 注册),就会以标准的注册表格式在CLSID键下创建一个键,它名字为服务器的GUID。下面是一个这样的例子:
{067DF822-EAB6-11cf-B56E-00A0244D5087}