Please note, this is a STATIC archive of website developer.mozilla.org from 03 Nov 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

创建Python XPCOM组件

Creating Applications with Mozilla 已经包含了一个教程用于编写简单的基于JavaScript和C++(实现nsISimple接口)的组件,本文阐述如何通过Python语言使用PyXPCOM创建相同的组件。

(Note that some details may be missing)

准备

如果你还没有PyXPCOM的二进制文件,请参考Building PyXPCOM以编译PyXPCOM的二进制文件。

Tip: 你可以从PythonExt得到PyXPCOM的二进制文件归档拷贝,解压缩xpi文件并得到任何你想要的东西。

如果你想在通常的Python可执行环境中使用PyXPCOM,你需要告诉Python在哪里可以找到PyXPCOM库。或许最好的办法就是在应用中设置变量PYTHONPATH指向'bin/python'目录。当然这在你的组件通过Mozilla被加载时是没有必要的因为Python加载器会完成sys.path的修改。

然后你可以

import xpcom

在任何Python模块里(大多数情况下是在你的组件中)。

定义接口

创建一个名为"nslPySimple.idl"的文件用于定义接口:

#include "nsISupports.idl"
[scriptable, uuid(2b324e9d-a322-44a7-bd6e-0d8c83d94883)]
interface nsIPySimple : nsISupports
{
    attribute string yourName;
    void write( );
    void change(in string aValue);
};

这与在这里使用nsISimple是相同的。理论上由于多个组件可以共享一个接口,因此使用了相同的接口文件。

需要特别留意一下,Python和JavaScript都是弱类型的语言,所以比较容易从一个到另一个传递信息。

Note: There are exceptions; see this discussion for information on the use of string and wstring for unicode transfer. See here for info on describing interfaces, and on which types can be used.

注册接口

在"components"目录中执行如下命令:

../xpidl -m typelib -w -v -I /usr/share/idl/mozilla/ nsIPySimple.idl

在Windows中你必须要将idl目录指定成Mozilla构建目录。例如:

xpidl.exe -m typelib -w -v -I C:\source\mozilla\obj-i686-pc-mingw32\dist\idl foo.idl

然后xpidl将创建nslPySimple.xpt文件并正确放置到目录中(如'components'目录)。

实现组件

不同于C++,PyXPCOM为你做了很多事情。

创建了一个名为"py_simple.py"的文件用于实际的代码(同样是在'components'目录中)。

from xpcom import components, verbose

class PySimple: #PythonTestComponent
    _com_interfaces_ = components.interfaces.nsIPySimple
    _reg_clsid_ = "{c456ceb5-f142-40a8-becc-764911bc8ca5}"
    _reg_contractid_ = "@mozilla.org/PySimple;1"
    def __init__(self):
        self.yourName = "a default name" # or mName ?

    def __del__(self):
        if verbose:
            print "PySimple: __del__ method called - object is destructing"

    def write(self):
        print self.yourName

    def change(self, newName):
        self.yourName = newName

接口下来是注册组件;这个步骤相同于其它组件,但在Python组件不可用的状态下会失败。

为了注册组件,你需要在bin目录中touch(创建)一个隐藏文件.autoreg,或者是删除xpti.dat文件。之后在下一次Mozilla启动时会重新构建组件的索引,包括任何'components'目录下新的组件。这对接下来通过命令行启动Mozilla以查看组件是否注册成功来讲非常有帮助。

生成实现模板

xpcom.xpt模块被用于内部以处理类型信息,但它有一个非常好的功能,可以为任何接口的Python实现生成一个模板。

以脚本的方式执行这个文件并且以接口名字作为参数。例如:

% cd c:\mozilla\bin\python\xpcom
% python xpt.py nsISample
class nsISample:
    _com_interfaces_ = xpcom.components.interfaces.nsISample
    # If this object needs to be registered, the following 2 are also needed.
    # _reg_clsid_ = "{a new clsid generated for this object}"
    # _reg_contractid_ = "The.Object.Name"

    def get_value( self ):
        # Result: string
        pass
    def set_value( self, param0 ):
        # Result: void - None
        # In: param0: string
        pass

正如你所见到的,输出的是有效的Python代码,并带有每个方法的基本的方法签名和有效的注释信息。

测试

为了看到执行结果,你需要从命令行启动Firefox,因为那才是执行结果被打印出来的地方。

文档标签和贡献者

 此页面的贡献者: du.wei
 最后编辑者: du.wei,