Python/XPCOM/C++ question.

Denis Suhanov suhoff at dslextreme.com
Thu Mar 6 08:37:02 CET 2003


Hello guys,

I am working on a project that uses mozilla's XPCOM to connect different
components. Some of them are written in C++  and some in (lovely) Python.

I had a problem today and althought I managed to find a solution, I'd really
like to know what was the cause of the it so maybe some of you would be so
kind to explain it to a newbie.

I have a component, written in Python, that parses a simple XML and returns
a list of objects. Each object is an instance of Python class that is
implementing corresponding XPCOM interface, but isn't an XPCOM component
(first, to avoid a performance hit related to component creation/deletion
and second, because none of them really have to be a component). Oh yes, and
they are all the objects of the same class (implementing the same
interface). Here is the interface declaration:

interface Parser {
    // parses a given file and returns an array of nsIEntry objects
    void do( in string fname, out unsigned long count,
                    [retval, array, size_is(count)] out nsIEntry result );
};

here is Python implementation schema of the function corresponding to the
interface method declared above:

# we should not declare the parameters for an array
# since PyXPCOM is going to take care about them for us
def parse( self, fname ):
    try:
        result = []
        # opens the file, sets the content handler, parses XML and creates
        # the resulting list here (skipped)

        # here we return  PyList object as an array (which is stated
        # to be perfectly legal, according to PyXPCom documentation)
        return result;
    except Exception, details:
        #  avoid getting Python error in C++
        raise ServerException, nsError.NS_ERROR_FAILURE

now when I was trying to  call the function, I realized that although every
time I was getting a valid array of pointers to nsISupport interface (I
could see that vtbl points to something like PythonXPCOM_Stub in debugger),
an attempt to call any nsIEntry's function on one of these pointer would
cause my program to crash. I've spent some time trying to investigate it
(and after spending several hours on that, I even stared annoying folks at
netscape.public.mozilla.xpcom conference with that question) and eventually
found out that if (in my C++ program that calls this Python method) I
explicitly call QueryInterface on the pointers returned in the array,
everything would work just fine (of course, that's introduced an additional
::Release call)

Now isn't that a bit surprising? I mean, the interface clearly states "we
are going to work with the interfaces to nsIEntry", then the C++ program
that calls the method prepared an array of typed pointers to nsIEntry
interface and finally PytXPCOM (unless I am missing something) is informed
about the type of interfaces expected (through *.xpt). I perfectly
understand that there should be a good reason for such a behavior, so the
only thing that I am trying to find out is what that reason is.

Thanks in advance!

Sincerely yours,
Denis






More information about the Python-list mailing list