An introduction to XPCOM

July 14, 2008

What’s XPCOM, you ask? XPCOM, which stands for Cross Platform Component Object Model, is a framework for writing cross-platform, modular software. As an application, XPCOM uses a set of core XPCOM libraries to selectively load and manipulate XPCOM components. XPCOM components can be written in C, C++, and JavaScript, and they can be used from C, C++, and JavaScript with extensions for Perl and Python that are under development (.

In addition to modularity, XPCOM offers agility across platforms. It supports just about any platform that hosts a decent C++ compiler, including:

  • Microsoft Windows (all flavors)
  • Linux
  • HP-UX
  • AIX
  • Solaris
  • OpenVMS
  • MacOS
  • BSD

The tools you need to write XPCOM software are: a C++ compiler, a Perl interpreter, and some GNU tools.

Some applications that use XPCOM include:

Although it isn’t an XPCOM application, Adobe Acrobat uses a modified version of the same JavaScript engine bundled with XPCOM. The point here is that the code base for XPCOM is well tested and widely used.

Microsoft COM and XPCOM

You might be wondering whether XPCOM is like Microsoft COM. The short answer is yes, and no. Component proxy support is one area of distinction. A component proxy is a fake component whose purpose is to impersonate another component that, for some reason, cannot be accessed directly by the code that wishes to use it. For example, the code may not be able to access a component directly because the component exists in another process, or on another machine.

Microsoft COM supports an elaborate proxy mechanism for coordinating how different types of applications talk to components, including those that run as separate programs or even on different machines. MSCOM allows you to create components with different threading models or restrict a component to a specific threading model. Components can be created as in process (running inside the application) or out of process (runs as a separate application). A single threaded component must have its own thread, and other threads must use a proxy mechanism to access it. Apartment threaded components can share a thread but still need a proxy. Free threaded components need no proxy mechanism inside the same process. It’s this built-in proxy mechanism in MSCOM that provides the appropriate amount of thread safety for components that have their own threading constraints.

XPCOM is tailored toward providing modular component support at the application level, so proxy services only support multiple threads sharing an otherwise non-reentrant component. If you wish to access a component remotely, you will have to write your own proxy to marshal data back and forth to the remote object. There are some existing components that can help you do this, so it isn’t actually as tough as it sounds.

At the microscopic level, XPCOM and MSCOM appear identical: Both are interface based and require every interface to derive from the same base interface. This base interface defines the three methods QueryInterface, AddRef, and Release. Despite this common ideological heritage, MSCOM and XPCOM components are not compatible or interchangeable — some sort of wrapper or glue code is required for the two to operate together. The embedding wrapper for Mozilla is a good example. It allows the browser engine to appear as an MSCOM ActiveX control while the browser engine internally operates on XPCOM components.

The biggest contrast between XPCOM and MSCOM is that XPCOM technology is open source. If you are developing MSCOM software and you are having trouble trying to understand the differences in how the MSCOM libraries load and create your components, you are at the mercy of whatever documentation is available. Fortunately, Microsoft has gone to great pains to evangelize their architecture and provide good documentation. However, if Microsoft changes the behavior of these system-level libraries, it can affect the behavior of your components, and the behavior of the applications that use them.

In contrast, the source code for the libraries that make up the XPCOM architecture are fully available for you to inspect, trace, and debug alongside your own application code. You can even modify the code base to extend the architecture yourself, as opposed to waiting for Microsoft to extend it for you (as they did when they evolved MSCOM from plain COM, to DCOM, and then COM+).

If you are not already familiar with open-source software, you may want to investigate some other notable open-source projects, such as: the Free Software Foundation’s family of GNU projects, OpenBSD, Linux, OpenLDAP, OpenSSL, Apache, and others (see Resources).

XPCOM, threads, CORBA, and more

You will also need to understand how XPCOM handles remote objects, threads, and scripting. Some XPCOM technology is inherited from OMG CORBA. CORBA is a platform- and language-neutral component technology standardized by the Object Management Group. It includes an overall architecture for procedure calls to remote objects, an Interface Definition Language (similar to that of COM and XPCOM), and a broad set of common object services.

Strictly speaking, XPCOM does not support remote objects like CORBA, but neither does XPCOM prevent you from writing a component that uses a socket or other means to talk to another component. Many XPCOM applications make use of HTTP as a means of issuing remote procedure calls to other components hosted on a Web server. There are even some components available for supporting SOAP. Another link to CORBA is XPCOM’s IDL (Interface Definition Language) compiler. Called XPIDL, it was derived from an open-source CORBA IDL compiler.

XPCOM does support threads. However, thread-safe components are the exception rather than the norm as most components are written to coexist inside the same main application thread. Components can be coded thread safe, and XPCOM uses a simple scheme to determine whether a component advertises itself as thread safe.

Thread support is well represented in XPCOM even on platforms that offer little or no direct thread support. XPCOM supports scripting through an additional layer (called XPConnect) that includes a JavaScript engine and a type library mechanism. This allows JavaScript code to manipulate XPCOM components and even allows components to be implemented in JavaScript, and accessible to C++ code.

Getting started with XPCOM

Suppose the company’s CTO asks you to be lead developer on your own XPCOM project. Here’s what you and any prospective team members will need to know to be competent for such a project. The programmers in your group will need to know C and C++ well. XPCOM makes use of C-style macros and C++ templates for smart pointers. Someone unfamiliar with these will have a hard time understanding the existing Mozilla code base, which serves as a giant living body of sample source code.

Anyone with any flavor of COM experience is a big plus — but even so, there will be a learning curve both in the coding infrastructure (templates and macros) and in the actual development tools. The body of code is robust enough that there is bound to be something the average programmer hasn’t seen before. If you are lucky, you can find someone — even an outside consultant — with some XPCOM experience to serve as a mentor to help new project members along and expedite their proficiency.

Barring that, the Web site is an excellent resource for information, as are the Mozilla newsgroups where developers like you and I can post technical questions, submit code fragments for review, and voice opinions on the future direction of XPCOM. Beware that a reorganization of the newsgroups is imminent — but you can expect a timely announcement on the Web site that will describe the changeover.

Here are some of the most helpful sites:

In addition to C++, you and your fellow developers need to know how to use an IDL compiler and understand the core XPCOM interface. You should also be able to describe the purpose of the interface methods QueryInterface, AddRef, and Release (in your sleep, and backwards and forwards).

You’ll need to understand the difficult component topic of aggregation. Aggregation is a means for placing a component inside another larger component where the larger component delegates the responsibility of some of its interfaces to the internal component. This is nothing more than information hiding, which is one of the tenets of object-oriented programming. The issue of aggregation arises from the fact that all XPCOM interfaces must include the QueryInterface method. This means that your code, when using a component, has the ability to switch from one interface to another. This creates a problem when trying to write a new component that extends another, existing component. The QueryInterface method on the pre-existing component must somehow be able to respond to requests for new, additional interfaces introduced by the new derived component without any prior knowledge of the new code. If that sounds a bit wicked, it is.

Finally, your project’s testing and QA team members will need to know how to write shell scripts and JavaScript. They will also need a working knowledge of the operating systems your cross-platform project intends to support. Their scripting knowledge will help expedite the writing of test scripts, and automate regression testing.

Although it doesn’t guarantee success, having these skills will allow your team — whether one person or many — to be productive in leveraging what XPCOM has to offer.