IDL Author's Guide - Rules and Syntax
-
An interface is declared with the interface keyword,
and the simplest possible interface is as follows:
interface nsIFoo { };To specify an interface's parent, follow the interface name with a colon and the parent name:
interface nsIFoo : nsIParent { };In XPCOM, all interfaces have an associated IID. Use the identifier attribute syntax to specify the uuid attribute:
[uuid(00000000-0000-0000-c000-000000000046)] interface nsIFoo : nsIParent { };If you wish to have a forward declaration for an interface, simply omit the interface definition and all parent and attribute data:
interface nsIForward;Methods and Attributes
-
An interface can have both methods and attributes. Attributes
are properties of interface objects, which can be read and
optionally set. The following is an interface with one method
(no return value, no parameters) named fun and an
integer-valued attribute named attr:
interface nsIFoo { attribute long attr; void fun(); };Methods can have any number of in, out or inout parameters, with a variety of types. The following interface shows parameters of different types and ``in-out-ness''2:
interface nsIStringStuff { void findStringLength(in string str, out long l); void concatenateStrings(in string str1, in string str2, out string result); void replaceChar(inout string str, in char from, in char to, in boolean foldCase); };You can specify a non-void return type for your method, but you should be aware of the code-generation rules. A non-void return type is converted to a trailing out parameter when the C++ is generated :
interface nsINonVoidReturn { string gimmeString(in string str, in long count); long gimmeLong(in boolean prime); };Attributes can be made read-only, by prepending the readonly keyword to the definition :
interface nsIThing { readonly attribute string lookButDontTouch; };
C++ get and set methods for attributes are automatically declared for attributes in the interface. An attribute name foo generates accessor methods GetFoo and SetFoo. Notice that the first letter of the attribute is changed to uppercase for the accessor method.
XPIDL code | Generated C++ header |
---|---|
interface nsIBar { attribute short foo; }; |
/* starting interface: nsIBar */ class nsIBar : { public: /* attribute short foo; */ NS_IMETHOD GetFoo(PRInt16 *aFoo) = 0; NS_IMETHOD SetFoo(PRInt16 aFoo) = 0; }; |
The xpidl compiler capitalizes method names when generating C++ headers. This is to support existing C++ convention in Mozilla, which is to use the InterCaps method naming style. The method name used in XPIDL will appear with the same capitalization to JavaScript, so the best practice is to match JavaScript convention by declaring attributes and method names in interCaps.
XPIDL code | Generated C++ header |
---|---|
interface nsISil { void twiddleSil(); }; |
/* starting interface: nsISil */ class nsISil { public: /* void twiddleSil (); */ NS_IMETHOD TwiddleSil(void) = 0; }; |
If for some reason the default name for a method or attribute
cannot be used, say, because that name conflicts with a Windows
macro, the binaryname(Name)
modifier can be used to
change the C++ symbol name. For example:
XPIDL code | Generated C++ header |
---|---|
interface nsINameConflicts { [binaryname(MessageMoz)] attribute AString message; [binaryname(PostMessageMoz)] void postMessage(in AString message); }; |
/* starting interface: nsINameConflicts */ class nsINameConflicts { public: /* [binaryname(MessageMoz)] attribute AString message; */ NS_IMETHOD GetMessageMoz(nsAString& message) = 0; NS_IMETHOD SetMessageMoz(const nsAString& message) = 0; /* [binaryname(PostMessageMoz)] void postMessage(in AString message); */ NS_IMETHOD PostMessageMoz(const nsAString& message) = 0; }; |
XPIDL provides several built-in types. The use of native types is also possible, though this may limit scriptability.
Type | C++ mapping |
---|---|
void | void |
boolean | PRBool |
octet | PRUint8 |
short | PRInt16 |
long | PRInt32 |
long long | PRInt64 |
unsigned short | PRUint16 |
unsigned long | PRUint32 |
unsigned long long | PRUint64 |
float | float |
double | double |
char | char |
wchar | PRUnichar |
string | char* |
wstring | PRUnichar* |
It is possible to use native types in XPIDL by declaring then using the native declaration syntax which works similar to a typedef in C++.
A native type can be given a name using the following syntax:
native name(native_type);
It is also possible to define reference and pointer types by combining [ref] or [ptr] with native:
XPIDL code | Generated C++ |
---|---|
[ref] native nsNativeFileRef(nsFileSpec); [ptr] native nsNativeFilePtr(nsFileSpec); interface foo { void openByRef(in nsNativeFileRef aFileSpecRef); void openByPtr(in nsNativeFilePtr aFileSpecPtr); }; |
/* starting interface: foo */ class foo { public: /* void openByRef (in nsNativeFileRef aFileSpecRef); */ NS_IMETHOD OpenByRef(nsFileSpec & aFileSpecRef) = 0; /* void openByPtr (in nsNativeFilePtr aFileSpecPtr); */ NS_IMETHOD OpenByPtr(nsFileSpec * aFileSpecPtr) = 0; }; |
Using native types in your code can be a good way to migrate existing interfaces. However, using native types in a method will mean that method is not scriptable.
-
When referencing interfaces defined in other files, you must
#include "filename.idl"
In XPIDL, #include only includes the file once, so
the #include statement does not need to be protected
by ifdefs as with the C preprocessor.
C-style enumerations are not supported, since the size of enums can be compiler-specific. Instead XPIDL supports defining constants that appear in the C++ and JavaScript mappings. Constants must be of type short or long, and must appear inside an interface declaration.
Other types are not supported for constants since they do not map into all languages or have memory management issues. To define a "constant" that is not a short or long, write a method that returns the value, or put the value into an attribute.
XPIDL code | C++ code |
---|---|
const short c1 = 1+1; | enum { c1 = 2 }; |
const short c2 = c1 * 5; | enum { c2 = 10 }; |
const long flag = 1 << 5; | enum { flag = 32 }; |
const float invalid_constant = 6.0; | Warning: const decl 'invalid_constant' was not of type short or long, ignored |
[Rules and Syntax] [Best Practices] [Keywords]
1: ``XP'' stands for ``cross-platform'', of course.
2: I crave a better name for this.
Mike Shaver Mike Ang Mike McCabe Last modified: Tue Oct 5 15:33:12 PDT 1999