r2 - 19 Aug 2005 - 16:57:35 - BrendanOConnorYou are here: OSAF >  Journal Web  >  ContributorNotes > AlecFlettNotes > PyXPCOMExperiments

PyXPCOM? Hacking

First goal: get to the repository from inside xpcshell

xpcshell is the javascript equivalent of running python from the command line - you get a little interactive shell. From there, you can get to any XPCOM-enabled components like this:

js> c = Components.classes["componentname"].createInstance()
(... information about the component ... )
js> 

My goal was to be able to open the chandler repository from xpcshell

Building mozilla against our python turned out to be a little tricky. The irony was in the end I think all I really needed was the ActiveState? Python, with our Python directory.

Once mozilla was built, the challenge was getting it to see our python. It seems that the ActiveState? Python in c:\windows\system32\python24.dll is the one that will be seen by mozilla's dist\bin\components\pyloader.dll, because the windows search path involves looking first in the windows directory first before checking the PATH environment variable.

I hacked the hell out of the loader to get it to load out library, but to no avail. Finally I renamed c:\windows\system32\python24.dll and managed to get it to load our python24.dll. Then the problem is that Python itself has no way to know where its home is, so I had to set PYTHONHOME to chandler\release\bin. (setting PYTHONPATH did not help here) I'm guessing there's a way to do this with Py_Initialize or something.

In the end, it turned out that the ActiveState? python24.dll works fine with our PYTHONHOME.

From there I set up some XPCOM components to allow me to get to python from JavaScript. First, nsIChandler.idl:

interface nsIChandler {
  void start();
};

Next, a python implementation:

import sys
sys.path.append('c:\alecf\tip\chandler\chandler');
sys.path.append('c:\alecf\tip\chandler\chandler\parcels');

from code import interact

class ChandlerMain:
    _com_interfaces_ = components.interfaces.nsIChandler
    _reg_clsid_ = "{9d6499dd-61b4-4510-9f33-0ad4a6cf6f41}"
    _reg_contractid_ = "Chandler"

    def start(self):
        interact()

I dumped this file in the components directory in mozilla.

Finally, I fired up xpcshell:

js> chandler = Components.classes["Chandler"].createInstance()
js> chandler.start()
Python 2.4.1 (#65, Mar 30 2005, 09:33:37) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>

Tada! Python running embedded inside of xpcshell, with full access to Chandler's repository!


I had to inherit from nsISupports to get my interface to work...

-- BrendanOConnor - 19 Aug 2005

Edit | WYSIWYG | Attach | Printable | Raw View | Backlinks: Web, All Webs | History: r2 < r1 | More topic actions
 
Open Source Applications Foundation
Except where otherwise noted, this site and its content are licensed by OSAF under an Creative Commons License, Attribution Only 3.0.
See list of page contributors for attributions.