mozilla
검색 결과

    Creating a Python XPCOM component

    현재 번역은 완벽하지 않습니다. 한국어로 문서 번역에 동참해주세요.

     

    모질라용 애플리케이션 만들기 에서 간단한 JavaScript 도는 (nsISimple 인터페이스로 구현된) C++ 컴포넌트를 만드는 튜토리얼을 이미 제공한 바 있고, 여기는 PyXPCOM을 이용해 파이썬으로 같은 컴포넌트를 어떻게 만드는지 보인다.

    (Note that some details may be missing)

    Preparation

    If a binary of PyXPCOM is not available, you will need to build it - see Building PyXPCOM

    If you wish to use PyXPCOM from a normal Python executable, you will need to tell Python where it can find the PyXPCOM library. This is probably best done by setting a PYTHONPATH variable pointing at the 'bin/python' directory in the application. This is not necessary when your components are loaded by Mozilla as the Python loader modifies sys.path.

    Then you can

    import xpcom
    

    in any Python module (mostly, in your component).

    Defining the interface

    Make a file named "nsIPySimple.idl", to define the interface:

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

    This is the same as the nsISimple interface used here . Theoretically, because several components can share an interface, the same file could be used.

    Pay special attention to types here - Python and JavaScript are both loosely-typed, so it's fairly easy to pass information from one to the other.

    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.

    Registering the interface

    In the "components" directory, execute :

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

    On Windows you must point to the idl directory as part of your Mozilla build. For example:

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

    xpidl will then create nsIPySimple.xpt, which should be placed correctly, (e.g. in the 'components' directory).

    Implementing the component

    Unlike C++, PyXPCOM does much of the work for you.

    Make a file named "py_simple.py" for the actual code (again, in the 'components' directory)

    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
    

    Then register your component; the procedure is the same for any component, but will not work if Python components weren't enabled.

    To register the component, touch the .autoreg (a hidden file) in the bin directory, or delete xpti.dat. Then, the next time Mozilla starts, it will rebuild the index of components, including any new one in the 'components' directory. It is helpful to then start Mozilla from the command line to see if new components register successfully.

    Generating implementation templates

    The module xpcom.xpt is used internally to process type information, but it has a nice feature - it can spit out a template for a Python implementation of any interface.

    Just execute this file as a script with the interface name as a param. For example:

    % 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
    

    As you can see, the output is valid Python code, with basic signatures and useful comments for each of the methods.

    Testing it

    To see this work, you will have to start Firefox from the command line, since that'll be where the stuff will be printed out.

    문서 태그 및 공헌자

    Contributors to this page: 아샬, teoli
    최종 변경: teoli,