Chapter 8. XPCOM- P2
8.1.3.2. Root interfaces
QueryInterface, Addref, and Release are required methods that are
implemented by every component. QueryInterface matches a specific
interface with its implementation class module. Addref and Release are
methods used for reference counting. When an instance of a component is
created, one or more pointers may reference that object. For each reference,
a count is incremented by one. When a reference is no longer used,
Release is called to decrement the count. You must hold a reference count
to ensure that no pointers reference an object after it is deleted. When
pointers try to access objects that are deleted, the application core dumps.
Reference counting can get tricky, which is why smart pointers manage
Addref and Release for you, as described in the later section Section
8.2.4.
Defining QueryInterface, Addref, and Release every time an
interface is created is clearly not very efficient. Instead, these methods are
defined in the base interface called nsISupports. All interfaces inherit from
this mother of all interfaces and don't need to redefine these three basic
functions.
XPIDL supports the C style syntax preparser directive #include to
include other IDL files -- not unlike MSCOM, which uses the import
statement. At the top of any IDL file that you create, you need to include
nsISupports:
#include "nsISupports.idl"
interface nsISimple : nsISupports {
readonly attribute string value;
};
Core IDL Types
The core types used in IDL interface files are listed in the file
xpcom/base/nsrootidl.idl. This file is included in nsISupports.
(This means it is included in every interface file, since all interfaces inherit
from nsISupports.) All interfaces used in a system are valid IDL types. For
example, nsISimple is a valid type to use as a method parameter or a method
return type. Some of the main types listed in this interface are:
typedef boolean PRBool;
typedef octet PRUint8;
typedef unsigned short PRUint16;
typedef unsigned short PRUnichar;
typedef unsigned long PRUint32;
typedef unsigned long long PRUint64;
typedef unsigned long long PRTime;
typedef short PRInt16;
typedef long PRInt32;
typedef long long PRInt64;
typedef unsigned long nsrefcnt;
typedef unsigned long nsresult;
typedef unsigned long size_t;
8.1.3.3. The XPIDL compiler
An IDL compiler is a tool that creates a binary distribution file called a type
library from an interface description source file. Since support for many
different platforms is a requirement for Mozilla, a modified version of the
libIDL compiler from the Gnome project is used. This variant is called the
XPIDL compiler and is primarily used to compile Mozilla's own dialect of
IDL, conveniently called XPIDL. The XPIDL compiler generates XPCOM
interface information, headers for XPCOM objects, and XPT type libraries
from which objects may be accessed dynamically through XPConnect. It can
also generate HTML files for documentation and Java class stubs. Another
feature of the XPIDL compiler is the option to generate C++ code stubs.
This feature creates nearly all the declaratory C++ code you need when you
start a new project, which makes XPIDL useful as a coding wizard that helps
you get started. Code generation is covered later in this chapter in the section
Section 8.2.5.
The XPIDL compiler is located in xpcom/typelib/xpidl/ in the
Mozilla sources. If you built Mozilla, you can add this directory to your
PATH:
$ PATH=$PATH:/usr/src/mozilla/xpcom/typelib/xpidl
Using the compiler is fairly easy. If you use the help command, you can see
the usage syntax and other basic information about the compiler:
$ ./xpidl --help
Usage: xpidl [-m mode] [-w] [-v] [-I path] [-o
basename] filename.idl
-a emit annotations to typelib
-w turn on warnings (recommended)
-v verbose mode (NYI)
-I add entry to start of include path for
``#include "nsIThing.idl"''
-o use basename (e.g. ``/tmp/nsIThing'') for
output
-m specify output mode:
header Generate C++ header
(.h)
typelib Generate XPConnect typelib
(.xpt)
doc Generate HTML documentation
(.html)
java Generate Java interface
(.java)
8.1.4. XPCOM Type Libraries
The key to the component architecture of XPCOM is the presence of binary-
independent interface files that are used uniformly across platforms,
languages, and programming environments. These interface files are
compiled into .xpt files by the XPIDL compiler. The Mozilla
components subdirectory is where type libraries and modules are
typically stored. If you create a cross-platform type library for your
component, you must place it in this directory for it to be accessible to
XPCOM.
8.1.4.1. Creating a type library file from an IDL interface
To create a (.xpt) typelib file, use the flag -m typelib with warning (-
w) and verbose (-v) modes turned on. -o is used for the name of the output
file and -I is used to specify paths to other IDL files you want to include.
To successfully compile your interface, you must always point to the
directory where nsISupports is located.
# include path to nsISupports.idl
$ $XPIDL_INC = /usr/src/mozilla/xpcom/base
#compile nsISimple.idl
$ xpidl -m typelib -w -v -I $XPIDL_INC \
> -o nsISimple nsISimple.idl
The file created after compilation is nsISimple.xpt. It provides the
necessary type information about your interface at runtime. Typelib files
enumerate the methods of interfaces and provide detailed type information
for each method parameter.
8.1.5. XPCOM Identifiers
To simplify the process of dynamically finding, loading, and binding
interfaces, all classes and interfaces are assigned IDs. An ID is a unique 128-
bit number that is based on universally unique identifiers (UUIDs) generated
by various tools such as uuidgen (which we will cover later in this
chapter). They are stored in the structure format defined below: