rahmad
rahmad

Reputation: 98

PyXPCOM component not loading in XULRunner

I'm planning to create XULRunner based application that need to interface with Python. The plan is to use PyXPCOM. Currently I'm teaching myself in using PyXPCOM and going through the example component developmnet in Creating a Python XPCOM component but can't get it to work.

I'm using Ubuntu 11.04 and my steps were:

  1. Created an application directory and copied my XULRUnner 5.x binary distribution into it the xulrunner subdirectory

  2. Successfully built PyXPCOM following Building PyXPCOM

  3. Followed the installation instructions in the PyXPCOM source README.txt file and copied the whole content of the directory obj/dist/bin into my xulrunner subdirectory and added the below line in the xulrunner/chrome.manifest file:

    manifest components/pyxpcom.manifest
    
  4. Created the nsIPySimple.idl file and placed it in my application components subdirectory:

    #include "nsISupports.idl"
    [scriptable, uuid(2b324e9d-a322-44a7-bd6e-0d8c83d94883)]
    interface nsIPySimple : nsISupports {
        attribute string yourName;
        void write( );
        void change(in string aValue);
    };
    
  5. Created the xpt file by executing the below command in my components subdirectory:

    [xul-sdk-path]/xpidl -m typelib -w -v -I [xul-sdk-path]/idl/ nsIPySimple.idl
    
  6. Created the nsIPySimple.py in my components subdirectory

    from xpcom import components, verbose
    
    class PySimple: #PythonTestComponent
        _com_interfaces_ = components.interfaces.nsIPySimple
        _reg_clsid_ = "{607ebc50-b8ba-11e0-81d9-001cc4c794e3}"
        _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
    
    PYXPCOM_CLASSES = [
        PySimple,
    ]
    
  7. Registered the python code by adding the following lines in my chrome.manifest file:

    interfaces  components/nsIPySimple.xpt
    component   {607ebc50-b8ba-11e0-81d9-001cc4c794e3} components/nsIPySimple.py
    contract    @mozilla.org/PySimple;1 {607ebc50-b8ba-11e0-81d9-001cc4c794e3}
    
  8. Created the Javascript function to call the Python method:

    function showMore() {
        try {
            testComp = Components.classes["@mozilla.org/PySimple;1"].name;
            alert(testComp);
            testComp = Components.classes["@mozilla.org/PySimple;1"].
                           createInstance(Components.interfaces.nsIPySimple);
    
            testComp.write();
        }
        catch (anError) {
            alert(anError);
        }
    }
    

But the Javascript code throws the following exception:

[Exception... "Component returned failure code: 0x80570015 
(NS_ERROR_XPC_CI_RETURNED_FAILURE) [nsIJSCID.createInstance]"  
nsresult: "0x80570015 (NS_ERROR_XPC_CI_RETURNED_FAILURE)"  
location: "JS frame :: chrome://reader/content/main.js :: 
showMore :: line 5"  data: no]

Any idea what happened or what I did wrong?

Thanks for the help and clarification!

Upvotes: 2

Views: 608

Answers (1)

Wladimir Palant
Wladimir Palant

Reputation: 57691

The error message indicates that createInstance() call resulted in an error. The good news: this means that everything preceding createInstance() succeeded (PyXPCOM is working and the component was loaded/registered correctly). http://code.google.com/p/pythonext/source/browse/samples/pyshell/components/pyShell.py indicates that _com_interfaces_ needs to be a list so maybe that's the problem here. If the supported interfaces aren't specified correctly then it makes sense that creating an instance fails.

Upvotes: 1

Related Questions