GitHub Gitee

XPCOM指南-2_使用XPCOM组件

Mozilla里组件是怎样获取和使用的呢? 在Mozilla里组件的使用分为三个部分:一个是Mozilla怎么找到这些二进制组件,另外两个对应了客户端访问XPCOM组件的两种方式。

1. 发现Mozilla组件

本书在编写时试图提供已冻结的XPCOM组件和他们的接口的参考信息。 Mozilla嵌入跟踪了当前冻结的接口。

Mozilla也提供了一些工具用于发现和显示在Gecko里的可运行的接口信息,例如工具"XPCOM Component Viewer"(下面会进行介绍),和MXR,基于Web的源代码查看工具。

如何把XPCOM组件的信息以良好的形式提供给潜在的用户,是一个挑战。 然而,就冻结的接口而言,通过这些组件实现的过程仍然在继续中。组件查看器不能区分组件是否冻结。 你在MXR里看到的源代码,被冻结的接口,你可以在顶部看到标记 @status frozen.

1.1 XPCOM 组件查看器 

XPCOM组件查看器(XPCOM Component Viewer)是你安装的浏览器的一个附件(放在了沙盒里,现在不再支持了)。 你可以试一试附件 XPCOMViewer,功能和XPCOM组件查看器相似。

XPCOM Component Viewer


2. 在你的CPP里使用XPCOM组件

XPConnect使得把XPCOM组件作为一个JavaScript访问变得很容易,但是在C++里使用XPCOM组件也不会困难多少。

下面是Managing Cookiescpp版本,代码参照javascript版本,使用C++替换了JavaScript

2.1 Managing Cookies from cpp

  1. nsCOMPtr<nsIServiceManager> servMan;  
  2.   
  3. nsresult rv = NS_GetServiceManager(getter_AddRefs(servMan));  
  4.   
  5. if (NS_FAILED(rv))  
  6.   
  7.   return -1;  
  8.   
  9. nsCOMPtr<nsICookieManager> cookieManager;  
  10.   
  11. rv = servMan->GetServiceByContractID("@mozilla.org/cookiemanager",  
  12.   
  13.                                      NS_GET_IID(nsICookieManager),  
  14.   
  15.                                      getter_AddRefs(cookieManager));  
  16.   
  17. if (NS_FAILED(rv))  
  18.   
  19.   return -1;  
  20.   
  21. PRUint32 len;  
  22.   
  23. deletedCookies->GetLength(&len);  
  24.   
  25. for (int c=0; c<len; c++)  
  26.   
  27.     cookieManager->Remove(deletedCookies[c].host,  
  28.   
  29.                           deletedCookies[c].name,  
  30.   
  31.                           deletedCookies[c].path,  
  32.   
  33.                           PR_FALSE);  


如果你使用C++,那么上面的代码向你展现了获取XPCOM组件的步骤。 

3. XPConnect:在Script里使用XPCOM组件

本章开始就讨论的CookieManager组件为我们从JavaScript角度进一步了解使用组件提供了一个很好的机会。 下面的代码片段来自MozillaCookieManager对话框,你可以看到通过getService()方法创建的CookieManager的一个单例,通过它提供的功能让用户可以通过用户界面加载和移除Cookie

3.1 Managing Cookies from JavaScript

  1. var cmgr = Components.classes["@mozilla.org/cookiemanager;1"]  
  2.   
  3.                      .getService();  
  4.   
  5. cmgr = cmgr.QueryInterface(Components.interfaces.nsICookieManager);  
  6.   
  7. function loadCookies() {  
  8.   
  9.   // load cookies into a table  
  10.   
  11.   var enumerator = cmgr.enumerator;  
  12.   
  13.   var count = 0;  
  14.   
  15.   var showPolicyField = false;  
  16.   
  17.   while (enumerator.hasMoreElements()) {  
  18.   
  19.     var nextCookie = enumerator.getNext();  
  20.   
  21.     nextCookie = nextCookie.QueryInterface(Components.interfaces.nsICookie);  
  22.   
  23.     /* .... */  
  24.   
  25. }  
  26.   
  27. function FinalizeCookieDeletions() {  
  28.   
  29.   for (var c=0; c<deletedCookies.length; c++) {  
  30.   
  31.     cmgr.remove(deletedCookies[c].host,  
  32.   
  33.                 deletedCookies[c].name,  
  34.   
  35.                 deletedCookies[c].path,  
  36.   
  37.                 false);  
  38.   
  39.   }   
  40.   
  41.   deletedCookies.length = 0;  
  42.   
  43. }  


除了CookieManager调用的他自己的方法外,注意XPConnect对象和方法,他们把XPCOM组件反射成了JavaScript.

组件是一个JavaScript对象,他控制着组件的连接,所有类被放如一个数组,你可以通过契约ID请求它。 为了在JavaScript里实例化一个XPCOM组件,你需要传递要请求得组件的契约ID

  1. var cmgr = Components.classes["@mozilla.org/cookiemanager;1"]  
  2.   
  3.                      .getService();  


返回的 cookiemanager对象提供了在类型库里定义的所有方法。 要使用CookieManager组件,你可以向下面这样写代码,从系统里删除所有的Cookie

  1. cmgr = Components.classes["@mozilla.org/cookiemanager;1"]  
  2.   
  3.                  .getService();  
  4.   
  5. cmgr = cmgr.QueryInterface(Components.interfaces.nsICookieManager);  
  6.   
  7. // delete all cookies  
  8.   
  9. function trashEm() {  
  10.   
  11.    cmgr.removeAll();  
  12.   
  13. }  

 

这个例子展现的XPConnect glue的另一个重要的功能,所有对象的QueryInterface方法从XPCOM里反射到了JavaScript里。 在C++里,你可以轻松的调用对象的这个方法。

4 服务 vs 常规实例

在设计时你应该考虑好,你的组件是通过服务还是常规实例的方式提供功能,现在通过本章你应该明白了关于组件的一些东东。 实际上,在例子里getService()方法的功能也可以

通过组件对象的createInstance()方法来实现,创建一个单独得而不是普通实例。

单例模式用于创建服务的相关信息,参见"XPCOM Services"记住,QueryInterface允许你查询一个对象支持的接口,在上面的例子中QueryInterface接口用于获取nsICookie接口,在实例里,JavaScript代码可以访问每一个cookie的名称和属性。

Note: cookie-manager-ui

注意UI不是组件的自身的一部分。 XPCOM使得通过MozillaXPFE访问组件功能变得很方便,正如 CookieManager展示的那样,但是组件本身没有提供UI

 

Note: private-xpcom-interfaces

这里有一些异常。XPCOM接口也可能是私有的。 私有的接口不需要在对外发布的IDL里公布。

Note: cookie-manager-in-tutorial

CookieManager 组件在本指南里用来实现 web locking的持久化(存储)功能。

posted @ 2012-12-29 10:27  shudingbo  阅读(494)  评论(0编辑  收藏  举报
GitHub Gitee