组件内部

Creating Components in C++
让我们开始检查怎么用C++写XPCOM组件,最常见的组件类型是用C++写,然后编译成dll。下图显示了你实现的动态库和XPCOM框架之间的关系。
组件内部_第1张图片

当你创建一个组件或模块,并编译成库时,必须要导出一个NSGetModule方法,NSGetModule方法是访问库的入口。在注册或注销组件时,或XPCOM需要查询组件或库实现哪些接口时,该方法被调用。本章将描述整个过程。除了NSGetModule之外,还有nsIModule 和nsIFactory实际控制着组件的创建,还有字符组和XPCOM  粘合部分。后者提供了易于开发的工具,如智能指针,通用模块支持和简单字符串实现。最大和最复杂的部分是组件特定的代码本身。

XPCOM Initialization
要理解为什么,何时调用组件,需要了解XPCOM的初始化过程。当程序启动,则可以初始化XPCOM。开始XPCOM的初始化可以由用户或者程序启动本身完成。嵌入Gecko的web浏览器,启动时通过嵌入式API初始化XPCOM。别的程序可能等到要用XPCOM时才启动初始化。这两种情况初始化XPCOM的过程都是一样的。当程序调用初始化时XPCOM启动,出入的启动参数可以配置XPCOM,包括自定义的目录。这时API的主要目的是改变XPCOM的搜索目录,
XPCOM启动的步骤:
  1. 程序启动XPCOM
  2. XPCOM发出一个通知表示已经启动
  3. XPCOM找到并处理组件清单
  4. XPCOM找到并处理类型库清单
  5. 如果有新组件,XPCOM注册它们:
         a。 XPCOM调用自动注册
        b 。XPCOM注册新组件
         c。XPCOM结束调用自动注册   
     6. XPCOM启动完成

XPCOM Registry Manifests
XPCOM用清单文件为本地系统保存关于组件的信息,有两种类型的清单:
• “ Component Manifests”
• “ Type Library Manifests”
Component Manifests.
当XPCOM启动时,它查找组件清单,名为compreg.dat。该文件列出了已经注册的组件,并保存了关于每个组件是干什么的信息。XPCOM用清单文件来确定哪些组件是被覆盖的。XPCOM把这个文件读到内存数据库
组件清单是组件和文件,组件和类的映射,包含以下内容:
  1. 定位在磁盘上的注册的组件文件的大小
  2. 类ID到位置的映射
  3. Contract ID 到Class ID映射

Type Library Manifests.
程序另一个重要文件是类型库清单,它在组件目录下,名为xpti.dat。它包含系统上所有类型库的位置和搜索路径。它也列出所有已知接口和定义接口的类型库文件的连接。类型库文件是XPCOM二进制组件框架的核心。
类型库清单包含以下信息:
  1. 所有类型库文件的位置
  2. 类型库中所有已知接口和结构定义的映射
用这两个文件的数据,XPCOM知道哪些组件库已经注册,实现了哪些接口。另外,它把组件和类型库关联起来。
下一节介绍如何挂钩XPCOM的启动和注册过程,使得组件的数据在清单中体现,如此一来,在启动的时候可以找到组件并注册。

Registration Methods in XPCOM
什么是XPCOM注册
简而言之,注册过程就是让XPCOM知道你的组件,如本节和下一节所述,你可以在安装时显示的注册你的组件,或者通过regxpcom程序,或者可以用自动注册方法,在服务管理器找到并注册组件到特定的目录:
• XPInstall APIs
• regxpcom command-line tool
• nsIComponentRegistrar APIs from Service Manager
注册过程相当复杂,本节介绍XPCOM的初始化,下一节介绍在代码里怎么做使得能让XPCOM注册组件。
一旦清单文件被读入,XPCOM检查是否有组件需要注册。有两种方式支持组件注册,第一种是用XPInstall,它是一种安装技术,有可能伴随着一个 Gecko程序, 在安装过程中注册的组件接口 。 另一种更明显的组件注册方法是用regxpcom程序,它是Mozilla的一部分,存在于Gecko SDK,regxpcom在默认的组件列表安装组件。
Gecko嵌入式程序也提供了自己的XPCOM组件安装方法,使用了nsIComponentRegistrar接口,一个程序可以提供一个非注册的组件目录,启动的时候自动注册组件,终止时自动卸载组件。
当注册过程开始,XPCOM给所有注册的观测者发出广播,表示开始注册一个新的组件。直到所有的组件注册完成,有发出一个通知表示所有的XPCOM的注册步骤已经完成。nsIObserver接口处理执行通知。

Autoregistration
自动注册在XPCOM有时候也叫注册,上一节我们讲述了用XPCOM注册组件的三个方法。有时候程序用nsIComponentRegistrar接口,使用自己的代码观察特定的目标并注册被添加的组件。这就是通常说的自动注册。你需要知道需要用你的组件的程序的安装和注册的需求是什么。

The Shutdown Process
当程序要关闭XPCOM,它调用ShutdownXPCOM,调用该方法时,发生以下事情:
  1. XPCOM给所有的观测者发出关闭通知
  2. XPCOM关闭组件管理器,服务管理器和相关服务
  3. XPCOM释放所有全局服务
  4. ShutdownXPCOM返回,程序正常退出

Component Loaders
组件可以用很多语言编写,目前本书讨论的是本地组件,提供NSGetModule的共享库。如果为Javascript安装一个组件加载器,你就可以写javascript组件。
为了 注册、注销、装置和管理不同的组件类型,XPCOM用组件加载器抽象了XPCOM组件和XPCOM的接口。该加载器负责初始化,装载,卸载和支持每个组件的nsIModule接口。组件加载器也支持脚本组件。
当创建一个本地组件,组件加载器查找组件共享库的导出符号,这里的本地包括所有可以生成动态库的语言,脚本语言和非本地语言不能创建本地库。要使用非本地XPCOM库,XPCOM需要有知道怎么出来这些类型组件的特殊的组件加载器。
XPConnect, 提供了一个组件加载程序,使不同类型,包括接口和它们的参数,可以使用JavaScript,每中XPCOM支持的语言都要有一个组件加载器。
组件内部_第2张图片
Three parts of a XPCOM Component Library
XPCOM至少有三个层次,从里到外包括:
  1. XPCOM核心对象
  2. 工厂代码
  3. 模块代码
XPCOM核心对象就是你要实现的功能。例如,对象可能启动一个网络下载并实现监听接口,或者可能提供内容类型处理。不管怎么样,它都是XPCOM组件的核心,其他层次支持它,并把它插入到XPCOM系统中,一个单独库可能有多个这样的核心对象。
核心对象的上一层是工厂代码,工厂对象提供了核心对象的抽象,第一章介绍了使用了工厂模式的工厂对象,在XPCOM库的这层中,工厂对象的低层核心对象的工厂。
再往外一层是模块代码,模块接口提供了另外一种抽象,这时工厂对象支持多个工厂。从组件库的外部,只有一个NSGetModule()入口。从这个入口,可以生成多个工厂和XPCOM对象。以下章节将详细讲述这些层次。这里我们只是介绍,工厂模式是由nsIFactory接口表示。模块层次由nsIModule表示, 大多数组件库只需要这两个接口,,还有nsISupport接口, 负责XPCOM负加载  识别,并利用其核心对象代码。
下一节我们将写真实的代码编译成组件库, 你会看到每一层是如何实现的以及每个接口的使用。

XPCOM Glue
XPCOM包含很多,大部分的XPCOM接口并不冻结, 只在Gecko的内部使用。XPCOM提供很多从AVL链表的数据结构,不用自己写链表,重用nsVoidArray或者其他可用的类是很有诱惑力的,但是这可能是致命的错误。任何时候类都可能出现异常行为。
XPCOM是一个非常开放的环境,在运行时可以通过 CID, Contract ID,  IID获取一个服务或者组件。最新统计XPIDL定义了超过1300个接口, 少于100是被冻结的,这意味着开发者有很多接口可用。如果在IDL组件中,一个接口没有 被显示标记为冻结,版本改变时可能导致你的组件被分解。

The Glue Library
通常你要避免任何解冻接口。可是,XPCOM提供一些解冻工具,在实际的组件编程中经常用到。 智能指针类,nsCOMPtr,可以做引用计数,而且很少出错。实际上并不冻结,也不是nsDebug,打印调试信息的类,或nsMemory,该类确保 每个人都使用相同的堆、通用的工厂和模块。不用 每个开发人员发现并把这些不同的文件复制到自己的应用程序中,取代的是,XPCOM提供单一的库,你可以连接到程序中,如下图所示,
组件内部_第3张图片
这就是粘合库,它在你的组件和XPCOM之间提供一个桥梁,或粘合层。粘合库的一个版本是建在XPCOM中, 当你的组件使用它时, 链接到这个库的快照。 它直接包括这些解冻类的一个副本,它允许改变 XPCOM库版本而不影响程序。

XPCOM String Classes
XPCOM使用的基本的字符串类型是nsAString 和nsACString . 字符串类实现这些抽象类,是XPCOM中另一组有用的解冻类。为了利用某些Gecko API, 大多数组件和嵌入应用程序的需要链接到一些字符串类。但是,Mozilla使用的字符串代码高度复杂。 nsEmbedString 和nsEmbedCString对组件开发来说是很轻的字符串类, 特别是在小型嵌入式应用程序。该字符串最低限度支持nsAString/nsACString字符串类。
在你的组件中, 你可以限制自己使用nsEmbedString或者使用其他字符串的所有功能。WebLock使用了nsEmbedString 。
组件内部_第4张图片
胶水库为XPCOM的公共函数提供了存根函数。当胶水库初始化,它动态装载XPCOM库的符号,避免组件直接连接到XPCOM库。

















































你可能感兴趣的:(gecko,XPCOM)