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,因为那才是执行结果被打印出来的地方。
Creating XPCOM components, on which this short tutorial is based.
A three-part tutorial on ibm developerWorks:
Getting to know PyXPCOM - info on building PyXPCOM (and maybe Mozilla) to get it to work.
Getting started with PyXPCOM, part 3 - Creating your own components. The problem with this one is that the sample code they give is slightly broken (it ends with a "retu" which shouldn't be there. I haven't tried it, but it looks like nothing is missing, so getting rid of the "retu" should make it work fine.).