用 JavaScript 建立 XPCOM 組件

來源:互聯網
上載者:User
作者: builder
2005-07-08 03:59 PM

隨著 Firefox 市場佔有率的持續攀升,跨平台元件物件模型( Cross Platform Component Object Model )也正在迅速地發展。我們這裡將給出一個例子,說明如何使用這種物件模型。

 Mozilla 瀏覽器正在開啟一個使用跨平台元件物件模型( XPCOM )的世界。 Mozilla 瀏覽器還引入了 XPConnect 技術,該技術允許組件在瀏覽器中執行,而且能夠用 JavaScript 進行開發。

XPCOM 組件與微軟的 COM 組件的工作類似,通過介面完成客戶和組件之間的通訊。 XPCOM 的基本介面是 nsISupports 。使用 nsISupports 的 QueryInterface 方法可以得到你指定的介面的資訊(包括介面所支援的方法和屬性)。

[被屏蔽廣告]

JavaScript XPCOM 組件必須使用介面定義語言( IDL )才能實現 nsISupport 介面。 IDL 檔案被建立並編譯成 XPT 類型庫。組件註冊器根據 XPT 檔案中的資訊使用 Mozilla 註冊組件。一旦組件成功註冊,你就可以在自己的代碼中使用 XPCOM 組件了。

在這個例子中,我將使用 JavaScript 建立一個樣本暴露 reverselt() 方法的 XPCOM 組件。這個方法接受一個字串類型的參數,並將字串中字元的順序進行反轉。

XPCOM 組件有三層,這三層分別是 XPCOM 物件層, nsIFactory 層和 nsIModule 層。 XPCOM 物件層是系統的核心;商務邏輯就放在這一層。 nsIFactory 層負責執行個體化 XPCOM 物件。 nsIModule 層負責註冊和提供 nsIFactory 層的抽象。這三層都是必須的,每一層都需要一些方法,從下面的代碼可以看到:

const MYCOMPONENT_CONTRACTID = '@mozilla.org/MyComponent;1';
const MYCOMPONENT_CID = Components.ID('{F 443406C -961D-4ecc-BF39-
C0E 9943C 72AE}');
const MYCOMPONENT_IID = Components.interfaces.nsIMyComponent;

function nsMyComponent() { }
nsMyComponent.prototype = {
    reverseIt: function(s) {
        var a = s.split("");
        a = a.reverse();
        return a.join("");
    },
    QueryInterface: function(iid) {
        if (!iid.equals(Components.interfaces.nsISupports) &&
            !iid.equals(MYCOMPONENT_IID))
            throw Components.results.NS_ERROR_NO_INTERFACE;
        return this;
    }
};

var nsMyComponentModule = {
    registerSelf: function(compMgr, fileSpec, location, type) {
        compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
        compMgr.registerFactoryLocation(MYCOMPONENT_CID,
                                        "MyComponent test",
                                        MYCOMPONENT_CONTRACTID,
                                        fileSpec,
                                        location,
                                        type);
    },
    getClassObject: function(compMgr, cid, iid) {
        if (!cid.equals(MYCOMPONENT_CID))
            throw Components.results.NS_ERROR_NO_INTERFACE;
        if (!iid.equals(Components.interfaces.nsIFactory))
            throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
        return nsMyComponentFactory;    
    },
    canUnload: function(compMgr) { return true; }
};
var nsMyComponentFactory = {
    createInstance: function(outer, iid) {
        if (outer != null)
            throw Components.results.NS_ERROR_NO_AGGREGATION;
        if (!iid.equals(MYCOMPONENT_IID) &&
            !iid.equals(Components.interfaces.nsISupports))
            throw Components.results.NS_ERROR_INVALID_ARG;
        return new nsMyComponent();
    }
};

function NSGetModule(comMgr, fileSpec) { return nsMyComponentModule; }

XPCOM 組件是以一個人能讀懂的名字註冊的。 XPCOM 的 Contract ID 與微軟 COM 組件中的 ProgID 類似。在我的例子中,這個值是 '@mozilla.org/MyComponent;1' 。

Contract ID 使用命名空間的概念來標識它們自己,所以在 Contract ID 前面加上 '@mozilla.org/' 首碼是很重要的。組件的 ID 是一個唯一標識組件的 128 位的 UUID 。組件對象的 ID() 方法接受一個 UUID 字串作為參數,並返回一個 nsID 對象,該對象用於註冊和執行個體化。(我使用 Windows 的 guidgen.exe 建立 UUID )。然後組件有一個介面 ID ( Interface ID, IID ),這個 IID 是在 XPT 檔案中所描述的介面的名字。在這個例子中, IID 為 nsIMyComponent 。

如果分析一下代碼,你就會發現實際的客戶商務邏輯是 nsMyComponent 類的 reverselt() 方法。其餘的代碼是用來使組件在 XPCOM 中工作的。如果你打算從我的例子代碼中建立自己的組件,你除了需要原樣拷貝所有的東西之外,還要在 nsMyComponent 類中添加自己的方法和屬性。

為了使 XPCOM 系統認識 nsIMyComponent 介面並匯出方法,你還必須提供一個 XPT 類型庫。提供 XPT 類型庫的方法是首先建立一個 IDL 檔案,然後使用 xpidl.exe 編譯它。下面是 MyComponent 的 IDL :

#include "nsISupports.idl"

[scriptable, uuid(F 443406C -961D-4ecc-BF39-C0E 9943C 72AE)]
interface nsIMyComponent : nsISupports {
    string reverseIt(in string s);
};

為了在 nsImyComponent 介面上實現 nsISupport 介面 IDL 檔案包含 nsISupport.idl 檔案。聲明 reverselt() 方法,指定它的傳回型別和它接受的參數。

我沒有找到 xpidl.exe 的一個普通下載,所以我是從 Mozilla.org 下載的零碎檔案中建立的。我已經成功地在 Windows 2000 和 XP 上面運行了該程式。你可以在 http://www.geocities.com/phil_perkins_1/articles/XPIDL/xpidl.zip 處找到這個普通下載。如果把它解壓到一個獨立的目錄,你就可以使用 -h 選項擷取說明它的用法的有關資訊。

為了使該例能夠運行,你需要把原始碼儲存在你的系統中 Mozilla 目錄下的“ components ”目錄下的“ nsMyComponent.js ”中。然後再在你解壓 xpidl.zip 的目錄下將 IDL 儲存為“ MyComponent.idl ”。從命令列定位到那個目錄,然後輸入:

xpidl -m typelib -w -v -e [path to IDL file]/MyComponent.xpt [path to IDL file]/MyComponent.idl

This should create a file called "MyComponent.xpt". Copy this file to the "components" directory under Mozilla.

這樣就會建立一個叫做“ MyComponent.xpt ”的檔案。將這個檔案拷貝到 Mozillia 下的“ components ”目錄下。

從命令列定位到 Mozilla 目錄,然後找到“ regxpcom.exe ”。鍵入“ regxpcom ”,然後敲斷行符號鍵。這樣就會向 Mozilla 註冊你的所有組件。然後你可以開啟“ compreg.dat ”檔案查看你的組件是否已經成功註冊。不要編輯這個檔案——這是一個自動產生的檔案。如果你的 Mozilla 視窗是開啟的,你應該在試圖使用新組件之前關閉所有的 Mozilla 視窗。要測試這個組件,將下面的 HTML 儲存到一個檔案中,然後在 Mozilla 中開啟它:

查看 JavaScript 控制台,看是否有什麼錯誤。你可以在 這裡 得到本例的原始碼。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.