зеркало из https://github.com/mozilla/gecko-dev.git
118 строки
5.3 KiB
HTML
118 строки
5.3 KiB
HTML
|
<HTML>
|
||
|
<HEAD>
|
||
|
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||
|
<META NAME="Author" CONTENT="Kipp E.B. Hickman">
|
||
|
<META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (WinNT; I) [Netscape]">
|
||
|
<TITLE>Gemini Object Model</TITLE>
|
||
|
</HEAD>
|
||
|
<BODY>
|
||
|
|
||
|
<H1>
|
||
|
Gemini Object Model</H1>
|
||
|
The gemini object model is a cross platform component object model modelled
|
||
|
after win32's IUnknown and COM. We do not support a C API to gemini at
|
||
|
this time.
|
||
|
<H2>
|
||
|
nsID</H2>
|
||
|
Like OSF's DCE, we use an "interface id" which is a unique identifer which
|
||
|
names the interface. The nsID and be used as a key into a cross platform
|
||
|
registry service to discover an implementation of an interface. Here is
|
||
|
the declaration of nsID:
|
||
|
<UL><TT>struct nsID {</TT>
|
||
|
<BR><TT> PRUint32 m0;</TT>
|
||
|
<BR><TT> PRUint16 m1, m2;</TT>
|
||
|
<BR><TT> PRUint8 m3[8];</TT>
|
||
|
|
||
|
<P><TT> inline nsbool Equals(const nsID& other) const {</TT>
|
||
|
<BR><TT> return</TT>
|
||
|
<BR><TT> (((PRUint32*) &m0)[0] == ((PRUint32*)
|
||
|
&other.m0)[0]) &&</TT>
|
||
|
<BR><TT> (((PRUint32*) &m0)[1] == ((PRUint32*)
|
||
|
&other.m0)[1]) &&</TT>
|
||
|
<BR><TT> (((PRUint32*) &m0)[2] == ((PRUint32*)
|
||
|
&other.m0)[2]) &&</TT>
|
||
|
<BR><TT> (((PRUint32*) &m0)[3] == ((PRUint32*)
|
||
|
&other.m0)[3]);</TT>
|
||
|
<BR><TT> }</TT>
|
||
|
<BR><TT>};</TT></UL>
|
||
|
On windows, the "uuidgen" program (provided with Visual C++) can be used
|
||
|
to generate these identifiers.
|
||
|
<H2>
|
||
|
nsISupports</H2>
|
||
|
This is the base class for all component objects. Not all objects are component
|
||
|
objects; these rules apply to objects which expose an interface which is
|
||
|
shared across dll/exe boundaries. Here is nsISupports:
|
||
|
<UL><TT>typedef nsID nsIID;</TT>
|
||
|
<BR><TT>class nsISupports {</TT>
|
||
|
<BR><TT>public:</TT>
|
||
|
<BR><TT> virtual nsqresult QueryInterface(const nsIID& aIID,</TT>
|
||
|
<BR><TT>
|
||
|
void** aInstancePtr) = 0;</TT>
|
||
|
<BR><TT> virtual nsrefcnt AddRef() = 0;</TT>
|
||
|
<BR><TT> virtual nsrefcnt Release() = 0;</TT>
|
||
|
<BR><TT>};</TT></UL>
|
||
|
The semantics of this interface are identical to win32's "COM" IUnknown
|
||
|
interface. In addition, the types are carefully mapped and the names are
|
||
|
the same so that if necessary we can "flip a switch" and have the windows
|
||
|
version (or any other platform that embraces COM) use the native COM IUnknown
|
||
|
without source code modification.
|
||
|
<H2>
|
||
|
Factory Procedures</H2>
|
||
|
Factory procedures use this design pattern
|
||
|
<UL><TT>nsqresult NS_NewFoo(nsIFoo** aInstancePtr, nsISupports* aOuter,
|
||
|
...);</TT></UL>
|
||
|
The return value is a status value (see nsISupports.h for the legal return
|
||
|
values); the first argument is a pointer to a cell which will hold the
|
||
|
new instance pointer if the factory procedure succeeds. The second argument
|
||
|
is a pointer to a containing component object that wishes to aggregate
|
||
|
in the Foo object. This pointer will be null if no aggregation is requested.
|
||
|
If the factory procedure cannot support aggregation of the Foo type then
|
||
|
it fails and returns an error if aggregation is requested.
|
||
|
|
||
|
<P>The following symbols are defined for standard error return values from
|
||
|
<TT>QueryInterface</TT> and from factory procedures:
|
||
|
<UL><TT>#define NS_FAILED(_nsresult) ((_nsresult) < 0)</TT>
|
||
|
<BR><TT>#define NS_SUCCEEDED(_nsresult) ((_nsresult) >= 0)</TT>
|
||
|
|
||
|
<P><TT>// Standard "it worked" return value</TT>
|
||
|
<BR><TT>#define NS_OK 0</TT>
|
||
|
|
||
|
<P><TT>// Some standard error codes we use</TT>
|
||
|
<BR><TT>#define NS_ERROR_BASE ((nsresult) 0xC1F30000)</TT>
|
||
|
<BR><TT>#define NS_ERROR_OUT_OF_MEMORY (NS_ERROR_BASE + 0)</TT>
|
||
|
<BR><TT>#define NS_ERROR_NO_AGGREGATION (NS_ERROR_BASE + 1)</TT>
|
||
|
<BR><TT>#define NS_NOINTERFACE ((nqresult) 0x80004002L)</TT></UL>
|
||
|
|
||
|
<H2>
|
||
|
nsIFactory</H2>
|
||
|
Factory classes should eventually replace factory procedures for major
|
||
|
classes. They provide an easy mechanism for placing code in DLLs. The nsIFactory
|
||
|
class is as follows:
|
||
|
<BR>
|
||
|
<UL><TT>class nsIFactory: public nsISupports {</TT>
|
||
|
<BR><TT>public:</TT>
|
||
|
<UL><TT>virtual nsresult CreateInstance(const nsIID &aIID,</TT>
|
||
|
<BR><TT>
|
||
|
nsISupports *aOuter,</TT>
|
||
|
<BR><TT>
|
||
|
void **aResult) = 0;</TT>
|
||
|
<BR><TT>virtual void LockFactory(PRBool aLock) = 0;</TT></UL>
|
||
|
<TT>};</TT></UL>
|
||
|
This interface is again identical to the COM version. More on registering
|
||
|
factories shortly.
|
||
|
<H2>
|
||
|
Error Handling</H2>
|
||
|
Because no exceptions are returned, error handling is done in the traditional
|
||
|
"error status value" method.
|
||
|
<H2>
|
||
|
Cross Platform Registry</H2>
|
||
|
A cross platform registry was written for the SmartUpdate feature of Communicator.
|
||
|
We will investigate it's usefulness for our purposes.
|
||
|
<H2>
|
||
|
Library Management</H2>
|
||
|
NSPR 2.x provides the cross platform mechanism for loading and unloading
|
||
|
libraries, and run time linking.
|
||
|
<BR>
|
||
|
</BODY>
|
||
|
</HTML>
|