
Chapter 8. XPCOM- P1
This chapter provides a high-level introduction to XPCOM component
technology. XPCOM can be difficult to master, but after reading this
chapter, you should have a good sense of what it is and the important part it
plays as Mozilla's core technology. You should be able to find and use
existing scriptable components in your own applications and create a simple
XPCOM component by using JavaScript or C++.
XPCOM permits a reusable code module to be globally accessible to a
Mozilla-based application. You do not need to worry about including
external source files in your application distribution and you can distribute
components by using XPInstall. This type of architecture makes the
development of core application services flexible and entirely modular.
The section Section 8.2.1 lets you create an interface from start to finish --
writing the implementation for that interface, compiling it into a type library,
registering it with Mozilla, and then testing the new component. One
advantage of using XPCOM is that you can create multiple implementations
for a single interface; following the JavaScript component section, we will
take the same nsISimple interface and implement it in C++ as well.
The section Section 8.2.5 includes some techniques and programming tasks
that are particular to C++ components, such as handling return values and
generating header files and useful macros. The section Section 8.2.7
introduces the XPCOM bindings for the Python language (pyXPCOM).
First, it provides an overview of XPCOM and how it relates to other
technologies used in Mozilla.
8.1. What Is XPCOM?

XPCOM is Mozilla's cross-platform component object model. Although it is
similar to Microsoft's COM technology, this chapter points out some
important differences.
Essentially, when you program in a component-based environment, you do
one of three things: you create a new component using existing components,
write a component that implements other components, and establish
interdependencies and a service network.
8.1.1. What Is a Component?
You've already seen components used in this book. In some cases, you may
have used the services of Mozilla components without knowing it -- for
example, when you created a XUL tree widget in the section Section 3.4.2 in
Chapter 3, and used its built-in layout and view capabilities. Some of this
functionality is defined in an interface called nsITreeView, which provides
specific methods and properties for a XUL tree, persisting its state, row, cell,
and column properties, navigation, and other object metadata used in a tree
object. Behind the scenes, you'll find an XPCOM-instantiated tree view
object where methods and properties associated with the XUL element are
accessed via DOM > JavaScript > XPConnect > XPCOM layers.
A component is a reusable or modular piece of code that implements a
clearly defined interface. In Mozilla, this code can exist as a singleton
service or an object instance. A singleton service is an object instance that is
created only once and then used by other code (usually called "callers,"
"clients," or "consumers"). An object instance is an object that is instantiated
once or many times. Components are written as classes that typically have
member variables and methods. The basic purpose of a component is to
implement a clearly defined set of APIs that exist in a public interface. The

interface exists separately so that the implementation is abstracted away, and
it can be changed without affecting the interface or breaking binary
compatibility. When interfaces are deployed in a production environment,
they are frozen, which means they are held in an immutable state --
theoretically for as long as the application exists. While MSCOM provides a
component-based programming model on Microsoft platforms, XPCOM
provides it on all platforms where Mozilla is available.
Example 8-1 shows how simple using XPCOM components can be. In two
lines, an XPConnect-wrapped nsIBookmarksService object is
instantiated, and one of its methods is called, providing easy access to this
XPCOM component from JavaScript.
Example 8-1. Using an XPCOM object in script
// create a bookmark service object in JS
var bmks =
Components.classes["@mozilla.org/browser/bookmarks-
service;1"].
getService(Components.interfaces.nsIBookmarksServic
e);
// call one of the object's methods:
// flush the bookmarks to disk if they've been
touched.
bmks.Flush( );

As you can see, the assignment of an XPCOM object to the variable bmks
takes only a single line. Once you are comfortable using XPCOM from
JavaScript, you can use any of Mozilla's scriptable interfaces in your
application. Once an object like bmks is created, as in Example 8-1, it can
be used to call any method in the nsIBookmarksService interface, of which
Flush( ) is an example.
8.1.2. XPConnect and the Component Object
As shown the previous example, the XPCOM object is called and
instantiated from script. For an interpreted language like JavaScript to call
and instantiate it, a bridge must bind JavaScript types to XPCOM types.
These type bindings are part of a technology called XPConnect.
In XPConnect, XPCOM interfaces, classIDs, and progIDs are stored as
global JavaScript objects and properties that can be manipulated directly
through a top-level object called Components. This object accesses any
component that is declared "scriptable" in an XPCOM IDL interface.
Through the Components object, you can access and use the services that
these interfaces provide. The Component object's top-level properties and
methods include:
QueryInterface
A method used to match an interface with a desired implementation.
The implementation can be in C, C++, JavaScript, Python, and other
languages for which appropriate bindings are created. You can have
multiple implementations for an interface. Through
QueryInterface, you can ask for and assign the desired interface
to its implementation. Each XPCOM object needs to implement

QueryInterface in order to return an instance of that object's
class:
js> var clz =
Components.classes['@mozilla.org/file/local;1'];
js> var inst = clz.getService( );
js> inst.QueryInterface(C.interfaces.nsILocalFile);
[xpconnect wrapped nsILocalFile @ 0x81b7040]
interfaces
A read-only object array containing all the interfaces declared
scriptable in the IDL file. The object name has the same name as the
interface it represents.
Components.interfaces.nsILocalFile
The source file for this particular interface, for example, is nsILocalFile.idl.
This XPIDL compiler compiles this file to produce a cross-platform binary
type library, nsILocalFile.xpt, which contains tokenized IDL in an
efficiently parsed form.
classes
A read-only array of all the XPCOM component classes indexed by
the ProgID (or human-readable name) of the component class. The
classes object has these properties associated with it:
toString Returns the string progID.
QueryInterface Used to QI this interface.
name Returns the string progid name.