mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-31 11:01:40 +00:00
Moving all important docs to gila. This is a documentation only change - not part of the tinderbox|release builds
This commit is contained in:
parent
0058480b59
commit
60d5f4ed17
File diff suppressed because it is too large
Load Diff
@ -1,117 +0,0 @@
|
||||
<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>
|
8
xpcom/doc/README
Normal file
8
xpcom/doc/README
Normal file
@ -0,0 +1,8 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>READ ME</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
|
||||
<H4><P>
|
||||
XPCOM documentation can be found at <a href="http://www.mozilla.org/projects/xpcom>www.mozilla.org/projects/xpcom</a>
|
@ -1,254 +0,0 @@
|
||||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="GENERATOR" content="Mozilla/4.51 [en] (WinNT; U) [Netscape]">
|
||||
<meta name="Author" content="Suresh Duddi">
|
||||
<title>TODO List for XPCOM</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<center>
|
||||
<h1>
|
||||
TODO List for XPCOM</h1></center>
|
||||
|
||||
<center>Last updated: 25 March 1999
|
||||
<br><a href="mailto:dp@netscape.com">Suresh Duddi</a></center>
|
||||
|
||||
<table BORDER WIDTH="100%" NOSAVE >
|
||||
<tr NOSAVE>
|
||||
<th NOSAVE>Task</th>
|
||||
|
||||
<th NOSAVE><a href="http://bugzilla.mozilla.org/bug_status.html#priority">Priority</a></th>
|
||||
|
||||
<th NOSAVE>Owner</th>
|
||||
|
||||
<th NOSAVE>MileStone complete/Status</th>
|
||||
</tr>
|
||||
|
||||
<tr BGCOLOR="#33CCFF" NOSAVE>
|
||||
<td NOSAVE>Move xpcom from using NR_*() functions (modules/libreg) to nsIRegistry
|
||||
(xpcom/src/nsRegistry.cpp)
|
||||
<ul>
|
||||
<li>
|
||||
Mainly you want to change all the Platform*() functions in nsComponentManager.cpp</li>
|
||||
|
||||
<li>
|
||||
Now we open/close the registry all the time. I want to keep the registry
|
||||
open all the time. That would get performance up.</li>
|
||||
|
||||
<li>
|
||||
Platform*() functions use the NR_*Raw() functions in some places. I wonder
|
||||
if the nsRegistry has a equivalent. If not we need to create them.</li>
|
||||
</ul>
|
||||
Mostly, there is equivalence between NR_*() calls and nsRegistry calls. </td>
|
||||
|
||||
<td>P2</td>
|
||||
|
||||
<td>Nick Ambrose <<a href="mailto:nicka87@hotmail.com">nicka87@hotmail.com</a>></td>
|
||||
|
||||
<td>3/22/1999 started
|
||||
<br>3/27/1999 Patch submitted
|
||||
<br>3/30/1999 landing
|
||||
<br><b>DONE</b></td>
|
||||
</tr>
|
||||
|
||||
<tr BGCOLOR="#33CCFF">
|
||||
<td>RegisterFactory() and RegisterComponent(..persist=0) ignoring CONTRACTID.
|
||||
Needs Fix.</td>
|
||||
|
||||
<td>P1</td>
|
||||
|
||||
<td>Nick Ambrose <<a href="mailto:nicka87@hotmail.com">nicka87@hotmail.com</a>></td>
|
||||
|
||||
<td>4/6/1999 started
|
||||
<br>4/7/1999 Patch submitted
|
||||
<br>4/12/1999 Patch Checked in
|
||||
<br><b>DONE</b></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Startup components: Some components need to be created at startup.
|
||||
Have a framework for them.</td>
|
||||
|
||||
<td>P1</td>
|
||||
|
||||
<td><a href="mailto:dp@netscape.com">Suresh Duddi</a></td>
|
||||
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>nsIRegistry access via Javascript.</td>
|
||||
|
||||
<td>P1</td>
|
||||
|
||||
<td></td>
|
||||
|
||||
<td>IDL of nsIRegistry will fix this says <a href="mailto:jband@netscape.com">John
|
||||
Bandhauer</a></td>
|
||||
</tr>
|
||||
|
||||
<tr BGCOLOR="#33CCFF" NOSAVE>
|
||||
<td NOSAVE>API changes: Remove all pathlist. XPCOM should support only
|
||||
paths.</td>
|
||||
|
||||
<td>P1</td>
|
||||
|
||||
<td><a href="mailto:dp@netscape.com">Suresh Duddi</a></td>
|
||||
|
||||
<td>4/2/1999 Checked in
|
||||
<br><b>DONE</b></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Fix xpcom from being initialized before main from static variables.</td>
|
||||
|
||||
<td>P1</td>
|
||||
|
||||
<td><a href="mailto:dp@netscape.com">Suresh Duddi</a></td>
|
||||
|
||||
<td>3/22/1999 Started.
|
||||
<br>- checked in a fixed xpcom initialization sequence.
|
||||
<br>- Now got to fix all code statically calling it. I know Netlib does.
|
||||
<br>- 4/1/1999 Fixed netlib on unix from static intialization. WIN is left.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Path handling: Use nsFileSpec instead of file path names. Char * pathnames
|
||||
are not intl, and cannot be stored in the registry. Plus that wont support
|
||||
mac aliases.
|
||||
<ul>
|
||||
<li>
|
||||
Possibly move autoreg out of xpcom</li>
|
||||
</ul>
|
||||
</td>
|
||||
|
||||
<td>P1</td>
|
||||
|
||||
<td><a href="mailto:dp@netscape.com">Suresh Duddi</a>
|
||||
<br><a href="mailto:rjc@netscape.com">Robert Churchill</a></td>
|
||||
|
||||
<td>3/24/1999 started
|
||||
<br><b>Blocked </b>on deciding which solution to pick.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Registry dump utility (regExport exists on windows) and about:registry
|
||||
(or) better yet an rdf data source for the registry.</td>
|
||||
|
||||
<td>P3</td>
|
||||
|
||||
<td><a href="mailto:dp@netscape.com">Suresh Duddi</a></td>
|
||||
|
||||
<td>4/5/1999 Fixed regExport to accurately dump the registry on win and
|
||||
unix.
|
||||
<br>- regExport needs to be compiled on the mac.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Replace use of nsVector (PL_Vector) with nsISupportsArray</td>
|
||||
|
||||
<td>P3</td>
|
||||
|
||||
<td></td>
|
||||
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>PATH argument to NSRegisterSelf() and NSUnregisterSelf() to be a nsISupports</td>
|
||||
|
||||
<td>P1</td>
|
||||
|
||||
<td></td>
|
||||
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr BGCOLOR="#33CCFF" NOSAVE>
|
||||
<td NOSAVE>Code Cleanup:
|
||||
<ul>
|
||||
<li>
|
||||
Registry path strings in nsComponentManager.cpp #defined</li>
|
||||
</ul>
|
||||
</td>
|
||||
|
||||
<td>P3</td>
|
||||
|
||||
<td>Nick Ambrose <<a href="mailto:nicka87@hotmail.com">nicka87@hotmail.com</a>></td>
|
||||
|
||||
<td>4/1/1999 started
|
||||
<br>4/5/1999 Patch submitted and checked in
|
||||
<br><b>DONE</b></td>
|
||||
</tr>
|
||||
|
||||
<tr BGCOLOR="#33CCFF">
|
||||
<td>Performance
|
||||
<ul>
|
||||
<li>
|
||||
Cache commonly used registry keys</li>
|
||||
</ul>
|
||||
</td>
|
||||
|
||||
<td>P1</td>
|
||||
|
||||
<td>Nick Ambrose <<a href="mailto:nicka87@hotmail.com">nicka87@hotmail.com</a>></td>
|
||||
|
||||
<td>4/1/1999 started
|
||||
<br>4/5/1999 Patch submitted and checked in
|
||||
<br><b>DONE</b></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Factories: Use previously created factories for object creation instead
|
||||
of creating the factory everytime the object needs to be created.
|
||||
<ul>
|
||||
<li>
|
||||
This is very tricky as the factory is owned by the component and when it
|
||||
decides to unload itself on a CanUnload() call, the factory will be released.
|
||||
Got to make sure that the component manager gets notified of this if it
|
||||
caches the factory.</li>
|
||||
</ul>
|
||||
</td>
|
||||
|
||||
<td>P2</td>
|
||||
|
||||
<td></td>
|
||||
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr BGCOLOR="#33CCFF" NOSAVE>
|
||||
<td NOSAVE>nsIAllocator: wrap it in a static api</td>
|
||||
|
||||
<td>P2</td>
|
||||
|
||||
<td><a href="mailto:jband@netscape.com">John Bandhauer</a></td>
|
||||
|
||||
<td NOSAVE>3/31/1999 started
|
||||
<br>4/2/1999 Check in
|
||||
<br><b>DONE</b></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>
|
||||
Documentation on XPCOM</h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<a href="TODO.html">TODO List</a> <<i>this page></i></li>
|
||||
|
||||
<li>
|
||||
XPCOM main page : <a href="http://www.mozilla.org/projects/xpcom">http://www.mozilla.org/projects/xpcom</a></li>
|
||||
|
||||
<li>
|
||||
<a href="xpcom-code-faq.html">Code FAQ</a></li>
|
||||
|
||||
<li>
|
||||
<a href="xpcom-component-registration.html">Component Registration</a></li>
|
||||
</ul>
|
||||
|
||||
<hr WIDTH="100%">
|
||||
</body>
|
||||
</html>
|
@ -1,93 +0,0 @@
|
||||
<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; U) [Netscape]">
|
||||
<TITLE>C++ Tips</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
|
||||
<H1>
|
||||
C++ Tips</H1>
|
||||
This is a compilation of tips on how to write cross-platform C++ code that
|
||||
compiles everywhere.
|
||||
<H2>
|
||||
General</H2>
|
||||
|
||||
<UL>
|
||||
<LI>
|
||||
Always use the nspr types for intrinsic integer types. The only exception
|
||||
to this rule is when writing machine dependent code that is called from
|
||||
xp code. In this case you will probably need to bridge the type systems
|
||||
and cast from an nspr type to a native type. The other exception is floating
|
||||
point; nspr defines PRFloat as a double (!).</LI>
|
||||
|
||||
<LI>
|
||||
Exceptions do not work everywhere so don't use them anywhere except in
|
||||
machine specific code, and then if you do use them in machine specific
|
||||
code you must catch all exceptions there because you can't throw the exception
|
||||
across xp code.</LI>
|
||||
|
||||
<LI>
|
||||
Templates do not work everywhere so don't use them anywhere.</LI>
|
||||
|
||||
<LI>
|
||||
Do not wrap include statements with an #ifdef. The reason is that when
|
||||
the symbol is not defined, other compiler symbols will not be defined and
|
||||
it will be hard to test the code on all platforms. An example of what <B>not</B>
|
||||
to do:</LI>
|
||||
|
||||
<BR>
|
||||
<UL><TT>#ifdef X</TT>
|
||||
<BR><TT>#include "foo.h"</TT>
|
||||
<BR><TT>#endif</TT>
|
||||
<BR><TT></TT> </UL>
|
||||
|
||||
<LI>
|
||||
For types that do not need operator= or a copy constructor, declare them
|
||||
yourselves and make them private. Example:</LI>
|
||||
|
||||
<BR>
|
||||
<UL><TT>class foo {</TT>
|
||||
<BR><TT>...</TT>
|
||||
<BR><TT>private:</TT>
|
||||
<BR><TT> // These are not supported and are not implemented!</TT>
|
||||
<BR><TT> foo(const foo& x);</TT>
|
||||
<BR><TT> foo& operator=(const foo& x);</TT>
|
||||
<BR><TT>};</TT></UL>
|
||||
|
||||
<LI>
|
||||
</LI>
|
||||
</UL>
|
||||
|
||||
<H2>
|
||||
Windows Compatability</H2>
|
||||
|
||||
<H2>
|
||||
Metroworks Compatability</H2>
|
||||
|
||||
<UL>
|
||||
<LI>
|
||||
MAC compilers do not handle #include path names in the same manner as other
|
||||
systems. Consequently #include statements should not contain path names,
|
||||
just simple file names. An example of what <B>not</B> to do:</LI>
|
||||
|
||||
<BR>
|
||||
<UL>#include "gemini/nsICSSParser.h"
|
||||
<BR> </UL>
|
||||
|
||||
<LI>
|
||||
</LI>
|
||||
</UL>
|
||||
|
||||
<H2>
|
||||
G++ Compatability</H2>
|
||||
|
||||
<UL>
|
||||
<LI>
|
||||
Use void in argument lists for functions that have no arguments (this works
|
||||
around a bug in g++ 2.6.3)</LI>
|
||||
</UL>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
@ -1,774 +0,0 @@
|
||||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Suresh Duddi">
|
||||
<meta name="GENERATOR" content="Mozilla/4.61 [en] (WinNT; U) [Netscape]">
|
||||
<title>Memory leaks fixing</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<center>
|
||||
<h1>
|
||||
Memory leaks fixing effort
|
||||
<hr WIDTH="100%"></h1></center>
|
||||
|
||||
<h2>
|
||||
Viewer</h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Startup (not the firsttime)</li>
|
||||
|
||||
<li>
|
||||
Show default page</li>
|
||||
|
||||
<li>
|
||||
Quit</li>
|
||||
</ul>
|
||||
|
||||
<table BORDER COLS=3 WIDTH="100%" >
|
||||
<tr>
|
||||
<th>Component</th>
|
||||
|
||||
<th>Leaks fixing by...</th>
|
||||
|
||||
<th>Status (<a href="#Stage 1: nsIModule conversion">nsIModule conversion</a>)</th>
|
||||
</tr>
|
||||
|
||||
<tr BGCOLOR="#FFFF99">
|
||||
<td COLSPAN="3"><b>bin/Components/</b></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>caps.dll</td>
|
||||
|
||||
<td>rjc</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>chardet.dll</td>
|
||||
|
||||
<td>kipp</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>history.dll</td>
|
||||
|
||||
<td>dp</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>jsloader.dll</td>
|
||||
|
||||
<td>kipp</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>lwbrk.dll</td>
|
||||
|
||||
<td>kipp</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>necko.dll</td>
|
||||
|
||||
<td>kipp</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>necko_resource.dll</td>
|
||||
|
||||
<td>kipp</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>necko_file.dll</td>
|
||||
|
||||
<td>kipp</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>nsgif.dll</td>
|
||||
|
||||
<td>kipp</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>nslocale.dll</td>
|
||||
|
||||
<td>cata</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>mimetype.dll</td>
|
||||
|
||||
<td>rjc</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>oji.dll</td>
|
||||
|
||||
<td>rjc</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>profile.dll</td>
|
||||
|
||||
<td>dp</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>raptorhtml.dll</td>
|
||||
|
||||
<td>kipp</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>raptorview.dll</td>
|
||||
|
||||
<td>dp</td>
|
||||
|
||||
<td>DONE (doesnt cache factory)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>rdf.dll</td>
|
||||
|
||||
<td>kipp</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>uconv.dll</td>
|
||||
|
||||
<td>cata</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>ucvlatin.dll</td>
|
||||
|
||||
<td>cata</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>ucharuti.dll</td>
|
||||
|
||||
<td>ftang</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>xpc3250.dll</td>
|
||||
|
||||
<td>kipp</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>xppref32.dll</td>
|
||||
|
||||
<td>dp</td>
|
||||
|
||||
<td>DONE </td>
|
||||
</tr>
|
||||
|
||||
<tr BGCOLOR="#FFFF99">
|
||||
<td COLSPAN="3"><b>bin/</b></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>jsdom.dll</td>
|
||||
|
||||
<td></td>
|
||||
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>raptorhtmlpars.dll</td>
|
||||
|
||||
<td>vidur</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>raptorgfxwin.dll</td>
|
||||
|
||||
<td></td>
|
||||
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>raptorweb.dll</td>
|
||||
|
||||
<td></td>
|
||||
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>raptorplugin.dll</td>
|
||||
|
||||
<td></td>
|
||||
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>raptorwidget.dll</td>
|
||||
|
||||
<td></td>
|
||||
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>
|
||||
Apprunner only</h2>
|
||||
|
||||
<table BORDER COLS=3 WIDTH="100%" >
|
||||
<tr>
|
||||
<th>Component</th>
|
||||
|
||||
<th>Leaks fixing by...</th>
|
||||
|
||||
<th>Status (<a href="#Stage 1: nsIModule conversion">nsIModule conversion</a>)</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>addrbook.dll</td>
|
||||
|
||||
<td>alecf</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>bookmarks.dll</td>
|
||||
|
||||
<td>rjc</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>brprof.dll</td>
|
||||
|
||||
<td>XXX</td>
|
||||
|
||||
<td>rjc says: This should be removed from build. See bug # 13732</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>chrome.dll</td>
|
||||
|
||||
<td>neeti</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>cnvts.dll</td>
|
||||
|
||||
<td>morse</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>cookie.dll</td>
|
||||
|
||||
<td>neeti</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>directory.dll</td>
|
||||
|
||||
<td>rjc</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>emitter.dll</td>
|
||||
|
||||
<td>alecf</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>ender.dll</td>
|
||||
|
||||
<td>morse</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>eventloop.dll</td>
|
||||
|
||||
<td>XXX - Don't do this</td>
|
||||
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>intlcmpt.dll</td>
|
||||
|
||||
<td>cata</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>jar50.dll</td>
|
||||
|
||||
<td>neeti</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>jsurl.dll</td>
|
||||
|
||||
<td>morse</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>mime.dll</td>
|
||||
|
||||
<td>mscott</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>mork.dll</td>
|
||||
|
||||
<td>bienvenu</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>mozbrwsr.dll</td>
|
||||
|
||||
<td>alecf</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>mozfind.dll</td>
|
||||
|
||||
<td>alecf</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>mozucth.dll</td>
|
||||
|
||||
<td>alecf</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>mozxfer.dll</td>
|
||||
|
||||
<td>alecf</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>msgbase.dll</td>
|
||||
|
||||
<td>putterman</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>msgcompo.dll</td>
|
||||
|
||||
<td>alecf</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>msgdb.dll</td>
|
||||
|
||||
<td>bienvenu</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>msgimap.dll</td>
|
||||
|
||||
<td>mscott</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>msglocal.dll</td>
|
||||
|
||||
<td>mscott</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>msgnews.dll</td>
|
||||
|
||||
<td>alecf</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>nativeapp.dll</td>
|
||||
|
||||
<td>XXX - Don't do this</td>
|
||||
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>necko_about.dll</td>
|
||||
|
||||
<td>kipp</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>necko_data.dll</td>
|
||||
|
||||
<td>kipp</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>necko_ftp.dll</td>
|
||||
|
||||
<td>kipp</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>necko_http.dll</td>
|
||||
|
||||
<td>kipp</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>nsjpg.dll</td>
|
||||
|
||||
<td>kipp</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>nspng.dll</td>
|
||||
|
||||
<td>kipp</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>nsprefm.dll</td>
|
||||
|
||||
<td>neeti</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>nsxpi.dll</td>
|
||||
|
||||
<td>neeti</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>pics.dll</td>
|
||||
|
||||
<td>neeti</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>prefwind.dll</td>
|
||||
|
||||
<td>alecf</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>rdfdomds.dll</td>
|
||||
|
||||
<td>neeti</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>regviewer.dll</td>
|
||||
|
||||
<td>neeti</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>related.dll</td>
|
||||
|
||||
<td>rjc</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>sample.dll</td>
|
||||
|
||||
<td>-sample- Don't do this one.</td>
|
||||
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>search.dll</td>
|
||||
|
||||
<td>rjc</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>stremcnv.dll</td>
|
||||
|
||||
<td>morse</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>strres.dll</td>
|
||||
|
||||
<td>cata</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>txmgr.dll</td>
|
||||
|
||||
<td>morse</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>txtsvc.dll</td>
|
||||
|
||||
<td>morse</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>ucvcn.dll</td>
|
||||
|
||||
<td>cata</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>ucvja.dll</td>
|
||||
|
||||
<td>cata</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>ucvko.dll</td>
|
||||
|
||||
<td>cata</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>ucvtw.dll</td>
|
||||
|
||||
<td>cata</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>ucvtw2.dll</td>
|
||||
|
||||
<td>cata</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>vcard.dll</td>
|
||||
|
||||
<td>XXX - Don't do this</td>
|
||||
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>wallet.dll</td>
|
||||
|
||||
<td>neeti</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>wlltvwrs.dll</td>
|
||||
|
||||
<td>neeti</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>xpctest.dll</td>
|
||||
|
||||
<td>neeti</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>xpiflash.dll</td>
|
||||
|
||||
<td>neeti</td>
|
||||
|
||||
<td>DONE</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br>
|
||||
<h2>
|
||||
How to fix leaks in a dll</h2>
|
||||
|
||||
<h3>
|
||||
<a NAME="Stage 1: nsIModule conversion"></a>Stage 1: nsIModule conversion</h3>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Convert dll to use nsIModule. Sample code is in <a href="http://lxr.mozilla.org/seamonkey/source/xpcom/sample/nsSampleModule.cpp">mozilla/xpcom/sample/nsSampleModule.cpp</a>.
|
||||
Things to watch out for:</li>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
nsIModule::UnregisterSelf should not return an Error.</li>
|
||||
|
||||
<li>
|
||||
Cache factories created by modules in the module.</li>
|
||||
</ol>
|
||||
The sample code does all this right. So sticking to closely is adviced.</ol>
|
||||
|
||||
<h3>
|
||||
<a NAME="Stage 2: Leak fixing"></a>Stage 2: Leak fixing <font color="#CC0000">(DONT
|
||||
DO THIS NOW)</font></h3>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
While in purify run <a href="http://lxr.mozilla.org/seamonkey/source/xpcom/tests/TestShutdown.cpp">bin/TestShutdown</a>
|
||||
on the dll. For this you will need to find a CID that the module implements.
|
||||
Then invoke TestShutdown as</li>
|
||||
|
||||
<ol>TestShutdown {123d4-4908-490840-409850}</ol>
|
||||
|
||||
<li>
|
||||
Make sure there are no leaks from the purify output.</li>
|
||||
|
||||
<br>Use ns<dll>Module::Shutdown() to release any global memory that
|
||||
is being leaked.</ol>
|
||||
|
||||
<hr WIDTH="100%">
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
</body>
|
||||
</html>
|
@ -1,262 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
|
||||
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
|
||||
<title>nsIClassInfo Overview</title>
|
||||
|
||||
<meta name="author" content="Mike Shaver">
|
||||
|
||||
<meta name="description" content="General Overview of nsIClassInfo infrastructure">
|
||||
|
||||
<style type="text/css">
|
||||
a:link, a:visited { text-decoration: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body bgcolor="#ffffff" link="#0000ee" vlink="#551a8b" alink="#0000ee">
|
||||
|
||||
<h2><code>nsIClassInfo</code> Overview</h2>
|
||||
Mike Shaver <<a href="mailto:shaver@mozilla.org">shaver@mozilla.org</a>
|
||||
><br>
|
||||
Last Modified: March 12, 2001<br>
|
||||
|
||||
<hr align="Left" width="100%" size="2">
|
||||
<h3>Table of Contents</h3>
|
||||
|
||||
<ul>
|
||||
|
||||
<li><a href="#What_is_nsIClassInfo">What is <code>nsIClassInfo</code>?</a></li>
|
||||
|
||||
<li><a href="#How_do_I_use_it">How do I use it?</a><a href="#What_is_nsIClassInfo"></a></li>
|
||||
|
||||
<li><a href="#Doesnt_that_break_the_COM">Doesn't that break the COM <code>
|
||||
QueryInterface</code> rules?</a><a href="#Doesnt_that_break_the_COM"></a></li>
|
||||
|
||||
<li><a href="#What_are_the_language_helpers_for">What are the "language
|
||||
helpers" for?</a><br>
|
||||
</li>
|
||||
|
||||
<li><a href="#That_sounds_useful_How_do_I_make_it">That sounds useful.
|
||||
How do I make that work with my code?</a></li>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>I'm writing C++ code, and</li>
|
||||
|
||||
<ul>
|
||||
|
||||
<li><a href="#Im_writing_C_code_and_I_use_the">I use the generic factory
|
||||
and <code>nsModuleComponentInfo</code></a></li>
|
||||
|
||||
<li><a href="#Im_writing_C_code_and_I_use_a_custom">I use a custom factory
|
||||
or a singleton service object</a><br>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
|
||||
<li><a href="#Im_writing_JS_code">I'm writing JS code.</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
<li><a href="#Whats_interface_flattening">What's "interface flattening"?</a><br>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<hr align="Left" width="100%" size="2">
|
||||
<h4><a name="What_is_nsIClassInfo"></a>What is <code>nsIClassInfo</code>?</h4>
|
||||
|
||||
<p><a href="http://lxr.mozilla.org/mozilla/source/xpcom/components/nsIClassInfo.idl#38"><code>
|
||||
nsIClassInfo</code></a> is an interface that provides information
|
||||
about a specific implementation class, to wit:</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li> a contract ID and class ID through which it may be instantiated;</li>
|
||||
|
||||
<li>the language of implementation (C++, JavaScript, etc.);</li>
|
||||
|
||||
<li> a list of the interfaces implemented by the class;</li>
|
||||
|
||||
<li>flags indicating whether or not the class is threadsafe or a singleton;
|
||||
and</li>
|
||||
|
||||
<li>helper objects in support of various language bindings.</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h4><a name="How_do_I_use_it"></a>How do I use it?</h4>
|
||||
|
||||
<p> To get the <code>nsIClassInfo</code> object for the implementation behind
|
||||
a given interface, simply <code>QueryInterface</code> for the nsIClassInfo
|
||||
interface:</p>
|
||||
|
||||
<blockquote>C++:<br>
|
||||
<code>nsCOMPtr<nsIClassInfo> info = do_QueryInterface(ifacePtr);</code><br>
|
||||
<br>
|
||||
JavaScript:<br>
|
||||
<code>var info = ifacePtr.QueryInterface(Components.interfaces.nsIClassInfo);</code></blockquote>
|
||||
|
||||
<p>It's important to note that this will usually return a <i>singleton</i>
|
||||
object: there often exists only one nsIClassInfo implementation for
|
||||
all implementations of a given class. This is very important, because it
|
||||
means that you can't <code>QueryInterface</code> back to the original object,
|
||||
no matter how hard you try.</p>
|
||||
|
||||
<h4><a name="Doesnt_that_break_the_COM"></a>Doesn't that break the COM
|
||||
<code>QueryInterface</code> rules?</h4>
|
||||
|
||||
<p>Quite. As discussed in <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=67699">
|
||||
bug 67699</a>, though, it's a reasonable concession to make in order
|
||||
to avoid an additional vtbl entry on every class that wants to export <code>
|
||||
nsIClassInfo</code> data.<br>
|
||||
</p>
|
||||
|
||||
<h4><a name="What_are_the_language_helpers_for"></a>What are the "language
|
||||
helpers" for?</h4>
|
||||
|
||||
<p>The language helpers are basically hooks for alternate language bindings
|
||||
to use for providing language-specific wrapping and manipulation behaviour,
|
||||
without adding code to every wrapped object. In <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=67699">
|
||||
bug 67669</a>, jband tells us what XPConnect does with the language helpers:</p>
|
||||
|
||||
<blockquote>
|
||||
<p>When wrapping an object xpconnect QIs the object for its classinfo
|
||||
(say 'foo'). If it has seen that foo classinfo pointer before then it knows
|
||||
that this object is a foo and it can reuse all the info is knows about foo
|
||||
objects. If it has never seen foo it will gather info (such as the JS helper)
|
||||
and remember that for future wrappings of foo objects.</p>
|
||||
<p> Assuming that the foo helper tells xpconnect to not bother QI'ing
|
||||
each foo instance for a per instance helper (or if the instances don't respond
|
||||
to QI for the helper) then the same foo helper is used on all calls from
|
||||
JS relating to the foo instances. </p>
|
||||
<p>What you may be missing is that methods on the helper (nsIXPCScriptable
|
||||
in the xpconnect case) *all* receive a pointer to the instance wrapper when
|
||||
called. I.e. the helper methods have an explicit 'self' param. This allows
|
||||
the helper to customize its response for each method call without requiring
|
||||
a helper per instance.</p>
|
||||
</blockquote>
|
||||
See <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=67699">bug 67699</a>
|
||||
for more interesting discussion about pluggable language helpers and decoupling
|
||||
them from specific wrapped classes.
|
||||
<p></p>
|
||||
|
||||
<h4><a name="That_sounds_useful_How_do_I_make_it"></a>That sounds useful.
|
||||
How do I make it work with my code?</h4>
|
||||
|
||||
<p>Why, yes, it <i>is</i> useful. To provide <code>nsIClassInfo</code>
|
||||
data for your class, you need to ensure that it returns an <code>nsIClassInfo</code>
|
||||
-implementing object when it is <code>QueryInterface</code>d for <code>
|
||||
nsIClassInfo</code> . Simple enough, but it can be even simpler through
|
||||
the use of a handful of helper macros/functions. Choose your own adventure:</p>
|
||||
|
||||
<h4><a name="Im_writing_C_code_and_I_use_the"></a>I'm writing C++ code,
|
||||
and I use the generic factory and <code>nsModuleComponentInfo</code>.</h4>
|
||||
|
||||
<p>First, make sure that your class has the <code>nsIClassInfo</code>
|
||||
helpers, by changing the <code>NS_IMPL_ISUPPORTS</code> line:</p>
|
||||
|
||||
<blockquote><code>NS_IMPL_ISUPPORTS2(nsSampleImpl, nsISample, nsIOther)</code><br>
|
||||
</blockquote>
|
||||
|
||||
<p>becomes</p>
|
||||
|
||||
<blockquote><code>NS_IMPL_ISUPPORTS2_CI(nsSampleImpl, nsISample, nsIOther)</code><br>
|
||||
</blockquote>
|
||||
|
||||
<p>This will provide an implementation of a helper function, named
|
||||
<code>nsSampleImpl_GetInterfacesHelper</code>, which handles the processing
|
||||
of <code>nsIClassInfo::getInterfaces</code>.</p>
|
||||
|
||||
<p>Next, in your module code, use <code>NS_DECL_CLASSINFO</code> to
|
||||
provide the rest of the per-class infrastructure (a global pointer into
|
||||
which to stash the <code>nsIClassInfo</code> object, and an extern declaration
|
||||
of the interfaces-helper, in case it's defined in another file):</p>
|
||||
|
||||
<blockquote><code>NS_DECL_CLASSINFO(nsSampleImpl)</code><br>
|
||||
</blockquote>
|
||||
|
||||
<p>You'll need one of these lines for each <code>nsIClassInfo</code>
|
||||
-supporting class represented in your <code>nsModuleComponentInfo</code>
|
||||
array.</p>
|
||||
|
||||
<p>Lastly, fill in the appropriate members of <code>nsModuleComponentInfo</code>
|
||||
to wire everything up:</p>
|
||||
|
||||
<blockquote><code>static nsModuleComponentInfo components[] =</code><br>
|
||||
<code>{</code><br>
|
||||
<code> {<br>
|
||||
"Sample Component", NS_SAMPLE_CID, NS_SAMPLE_CONTRACTID,
|
||||
<br>
|
||||
nsSampleImplConstructor,</code><br>
|
||||
<code> nsSampleRegistrationProc,</code><br>
|
||||
<code> nsSampleUnregistrationProc,</code><br>
|
||||
<code> nsnull /* no factory destructor */,</code><br>
|
||||
<code><font color="#ff0000"> NS_CI_INTERFACE_GETTER_NAME(nsSampleImpl),
|
||||
/* interface getter */</font></code><br>
|
||||
<code> nsnull /* no language helper */,</code><br>
|
||||
<code><font color="#ff0000"> &NS_CLASSINFO_NAME(nsSampleImpl),
|
||||
/* global class-info pointer */</font></code><br>
|
||||
<code> 0 /* no class flags */<br>
|
||||
}</code><br>
|
||||
<code>};</code><br>
|
||||
</blockquote>
|
||||
|
||||
<p>If you want to add a callback which provides language-helper
|
||||
objects, replace the last <code>nsnull</code> with your callback. See the
|
||||
<a href="http://lxr.mozilla.org/mozilla/source/xpcom/components/nsIClassInfo.idl"><code>
|
||||
nsIClassInfo</code> IDL file</a> for details on language helpers and
|
||||
other esoterica.</p>
|
||||
<p><b><i>Note</i></b>: the details of these macros may change
|
||||
slightly over the next week or so, as we refine a system for using table-driven
|
||||
QI and sharing data between QI and the class-info calls.<br>
|
||||
</p>
|
||||
|
||||
<h4><a name="Im_writing_C_code_and_I_use_a_custom"></a>I'm writing
|
||||
C++ code, and I use a custom factory or a singleton service object.</h4>
|
||||
|
||||
<p>You need some utility macros, don't ya? We're working
|
||||
on it. (You should really use the generic factory and module, though.
|
||||
See <a href="http://lxr.mozilla.org/seamonkey/source/intl/uconv/src/nsUConvModule.cpp">
|
||||
nsUConvModule.cpp</a> for an example of how to use <code>nsModuleComponentInfo</code>
|
||||
and the generic modules even when you have highly-custom registration
|
||||
requirements.)</p>
|
||||
|
||||
<h4><a name="Im_writing_JS_code"></a>I'm writing JS code.</h4>
|
||||
You poor thing. You suffer without even a GenericModule helper. We're
|
||||
<a href="http://bugzilla.mozilla.org/show_bug.cgi?id=71689">working on
|
||||
that</a>, too.
|
||||
<h4><a name="Whats_interface_flattening"></a>What's "interface
|
||||
flattening"?</h4>
|
||||
|
||||
<p></p>
|
||||
<p> Interface flattening is a way to present multiple interfaces
|
||||
of the same object to a language binding, without requiring explicit <code>
|
||||
QueryInterface</code> calls. Consider the following interfaces and
|
||||
an object <code>obj</code> that implements both of them:</p>
|
||||
<blockquote>
|
||||
<p><code>interface nsIFoo : nsISupports {<br>
|
||||
void fooMeth(in string message);<br>
|
||||
};</code></p>
|
||||
<p><code>interface nsIBar : nsISupports {<br>
|
||||
void barMeth(in PRUint32 meaning);<br>
|
||||
};</code></p>
|
||||
</blockquote>
|
||||
<p>You could use the following code to call both fooMeth and
|
||||
barMeth without any QueryInterface:<br>
|
||||
</p>
|
||||
<blockquote><code>obj.fooMeth("welcome to foo");<br>
|
||||
obj.barMeth(42);</code></blockquote>
|
||||
<p>Pretty, no? Pretty, yes. </p>
|
||||
<p>There are also intricacies related to conflicting method
|
||||
names and the difference between interface sets that are part of a contract's
|
||||
promise and those which are simply artifacts of the implementation, but they're
|
||||
beyond the scope of this overview.<br>
|
||||
<br>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
@ -1,487 +0,0 @@
|
||||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="GENERATOR" content="Mozilla/4.61 [en] (X11; U; Linux 2.2.5-15 i686) [Netscape]">
|
||||
<title>xpcom-review</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<center>
|
||||
<h1>
|
||||
XPCOM Brown Bag I</h1></center>
|
||||
|
||||
<center>Suresh Duddi <<a href="mailto:dp@netscape.com">dp@netscape.com</a>>
|
||||
<br>August 17, 1999
|
||||
<hr WIDTH="100%"></center>
|
||||
|
||||
<h3>
|
||||
Terminology</h3>
|
||||
|
||||
<table BORDER WIDTH="100%" NOSAVE >
|
||||
<tr NOSAVE>
|
||||
<td NOSAVE>Interface</td>
|
||||
|
||||
<td>Contract betwen the implementation and usage. A pure virtual abstract
|
||||
base class with no data members. eg. nsIZip</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>IID</td>
|
||||
|
||||
<td>Interface ID {xxxxx-xxx-xxx-xxxxxx} a unique number that identifies
|
||||
the Interface being talked about</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>nsISupports</td>
|
||||
|
||||
<td>The mother of all interfaces. All interfaces ultimately inherit from
|
||||
this. Provides refcounting. The IID and definition has been carefully choosen
|
||||
so as to be binary compatible with COM.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Component</td>
|
||||
|
||||
<td>An implementation of a set of interfaces identified by a CLSID</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Object</td>
|
||||
|
||||
<td>An instance of a Component</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>CLSID</td>
|
||||
|
||||
<td>Component ID {xxxxx-xxx-xxx-xxxxxx} a unique number that identifies
|
||||
a component</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Module</td>
|
||||
|
||||
<td>A packaging of a set of Components (ie) a DLL</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Factory</td>
|
||||
|
||||
<td>An object whose sole purpose is creation of objects of a particular
|
||||
component. There exists only one factory for every Component (CLSID). The
|
||||
IID and definition has been carefully choosen so as to be binary compatible
|
||||
with COM. nsIFactory</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>ClassObject</td>
|
||||
|
||||
<td>Same object as factory.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>ContractID</td>
|
||||
|
||||
<td>A String name for a Component.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>ComponentManager</td>
|
||||
|
||||
<td>Central Object of XPCOM that provides API for object creation and management.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>ServiceManager</td>
|
||||
|
||||
<td>A singleton manager. Holds and manages singleton references to objects
|
||||
for application. Going to be merged with the componentmanager.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Service</td>
|
||||
|
||||
<td>A singleton object within an application.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Registry</td>
|
||||
|
||||
<td>A hierarchical attribute-value pair storage.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>XPIDL</td>
|
||||
|
||||
<td>Cross Platform Interface Definition Language. Language for expressing
|
||||
interfaces.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Typelib</td>
|
||||
|
||||
<td>A storage for meta information about interfaces. Interfaces expressed
|
||||
in IDL have their meta information maintained in Typelib automatically.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>XPConnect</td>
|
||||
|
||||
<td>Ability to call c++ implementations of interfaces expressed in IDL
|
||||
from javascript and viceversa.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3>
|
||||
An Interface</h3>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
E.g Image Decoder <a href="http://lxr.mozilla.org/seamonkey/source/modules/libimg/public_com/nsIImgDecoder.h">nsIImgDecoder</a></li>
|
||||
|
||||
<br>
|
||||
<li>
|
||||
Dont put data members</li>
|
||||
|
||||
<li>
|
||||
Return value of member function should always be <tt>nsresult using the
|
||||
NS_IMETHOD macro.</tt></li>
|
||||
|
||||
<li>
|
||||
Use XPIDL for interface header files</li>
|
||||
|
||||
<li>
|
||||
Useful Macros if not using XPIDL</li>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_DEFINE_STATIC_IID_ACCESSOR">NS_DEFINE_STATIC_IID_ACCESSOR</a>
|
||||
- Defines static GetIID() method for an interface</li>
|
||||
|
||||
<li>
|
||||
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_IMETHOD">NS_IMETHOD</a>
|
||||
- Prototypes return value of interface function declaration</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<h3>
|
||||
The Component</h3>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
E.g GIF Image Decoder nsGIFDecoder <a href="http://lxr.mozilla.org/seamonkey/source/modules/libimg/gifcom/nsGIFDecoder.h">nsGIFDecoder.h</a>,
|
||||
<a href="http://lxr.mozilla.org/seamonkey/source/modules/libimg/gifcom/nsGIFDecoder.cpp">nsGIFDecoder.cpp</a></li>
|
||||
|
||||
<br>
|
||||
<li>
|
||||
Useful Macros</li>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_DECL_ISUPPORTS">NS_DECL_ISUPPORTS</a>
|
||||
- Declares all methods of nsISupports. Used in implementation declaration
|
||||
header file.</li>
|
||||
|
||||
<li>
|
||||
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_INIT_ISUPPORTS">NS_INIT_ISUPPORTS</a>
|
||||
- nitilize the base class ISupports. Used in constructor of implementation.</li>
|
||||
|
||||
<li>
|
||||
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_IMPL_ISUPPORTS">NS_IMPL_ISUPPORTS</a>
|
||||
- Implement the nsISupports functions. Used in implementation file.</li>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_IMPL_ADDREF">NS_IMPL_ADDREF</a>
|
||||
- Implementation of nsISupports::Release()</li>
|
||||
|
||||
<li>
|
||||
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_IMPL_RELEASE">NS_IMPL_RELEASE</a>
|
||||
- Implementation of nsISupports::AddRef()</li>
|
||||
|
||||
<li>
|
||||
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_IMPL_QUERY_INTERFACE">NS_IMPL_QUERY_INTERFACE</a>
|
||||
- Implementation of nsISupports::QueryInterface() for one IID</li>
|
||||
|
||||
<li>
|
||||
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_IMPL_ISUPPORTS2">NS_IMPL_ISUPPORTS2</a>
|
||||
- Implements the nsISupports function with QueryInterface for two IIDs</li>
|
||||
|
||||
<br> </ul>
|
||||
|
||||
<li>
|
||||
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_DEFINE_IID">NS_DEFINE_IID</a>
|
||||
- Define a variable of type nsIID initialized with a struct representatio
|
||||
of an IID</li>
|
||||
|
||||
<li>
|
||||
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_GET_IID">NS_GET_IID</a>
|
||||
- Use this instead of nsIFoo::GetIID() or NS_DEFINE_IID()...</li>
|
||||
|
||||
<li>
|
||||
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_DEFINE_CID">NS_DEFINE_CID</a>
|
||||
- Define a variable of type nsCID intialized with a struct representation
|
||||
of the CLSID</li>
|
||||
|
||||
<br>
|
||||
<li>
|
||||
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_IMETHODIMP">NS_IMETHODIMP</a>
|
||||
- Prototypes return value for interface functions implementation. Used
|
||||
in implementation file.</li>
|
||||
|
||||
<li>
|
||||
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_ADDREF">NS_ADDREF</a>,
|
||||
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_IF_ADDREF">NS_IF_ADDREF</a>
|
||||
- Addref an object by client</li>
|
||||
|
||||
<li>
|
||||
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_ADDREF_THIS">NS_ADDREF_THIS</a>
|
||||
- Addref used in object implementation. Dont need this if using NS_IMPL_ADDREF</li>
|
||||
|
||||
<li>
|
||||
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_RELEASE">NS_RELEASE</a>,
|
||||
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_IF_RELEASE">NS_IF_RELEASE</a>
|
||||
- Release an object by client</li>
|
||||
|
||||
<li>
|
||||
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_RELEASE_THIS">NS_RELEASE_THIS</a>
|
||||
- Released used in object implementation. Dont need this if using NS_IMPL_RELEASE</li>
|
||||
|
||||
<li>
|
||||
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_RELEASE2">NS_RELEASE2</a>
|
||||
- Release and get the refcount. Useful to check if refcount hit Zero.</li>
|
||||
|
||||
<br> </ul>
|
||||
|
||||
<li>
|
||||
Generic Factory - A generic factory implementation with callback ability
|
||||
for object creation. Simplies factory implementation.</li>
|
||||
</ul>
|
||||
|
||||
<h3>
|
||||
Object Creation</h3>
|
||||
|
||||
<ul><tt>rv = compMgr->CreateInstance(imgContractID, NULL, <a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_GET_IID">NS_GET_IID</a>(nsIImgDecoder),
|
||||
(void **)&imgdec);</tt>
|
||||
<br>
|
||||
<li>
|
||||
It is preferable to use the NS_GET_IID() version of getting iid instead
|
||||
of the old way</li>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
NS_DEFINE_IID(kImgDecodeIID, NS_IIMGDECODER_IID);</li>
|
||||
|
||||
<br>and then using kImgDecoderIID for the IID
|
||||
<li>
|
||||
<b>DO NOT USE nsIImgDecoder::GetIID()</b></li>
|
||||
</ul>
|
||||
|
||||
<li>
|
||||
The component manager does this on a CreateInstance()</li>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
map ContractID to CLSID</li>
|
||||
|
||||
<li>
|
||||
Get module object for dll which implements component CLSID</li>
|
||||
|
||||
<li>
|
||||
nsISupports classObject = module->GetClassObject()</li>
|
||||
|
||||
<li>
|
||||
nsIFactory factory = classObject->QueryInterface(NS_GET_IID(nsIFactory));</li>
|
||||
|
||||
<li>
|
||||
return factory->CreateInstance(IID);</li>
|
||||
</ul>
|
||||
|
||||
<li>
|
||||
<b>[hint]</b> Use nsCOMPtr</li>
|
||||
|
||||
<br>
|
||||
<ul><tt>nsCOMPtr <nsIImgDecoder> imgdec;</tt>
|
||||
<br><tt>rv = compMgr->CreateInstance(imgContractID, NULL, <a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_GET_IID">NS_GET_IID</a>(nsIImgDecoder),
|
||||
<font color="#990000">getter_AddRefs(imgdec)</font>);</tt></ul>
|
||||
</ul>
|
||||
|
||||
<h3>
|
||||
Object Release</h3>
|
||||
|
||||
<blockquote><tt>NS_IF_RELEASE(obj);</tt>
|
||||
<p>It should be noted that release and addref are directly talking to the
|
||||
object with no intermediaries. The macro NS_*_RELEASE() set the object
|
||||
to NULL.</blockquote>
|
||||
|
||||
<h3>
|
||||
Component Registration Process</h3>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<a href="http://lxr.mozilla.org/seamonkey/source/xpcom/components/nsIModule.idl">nsIModule.idl</a></li>
|
||||
</ul>
|
||||
|
||||
<ul>At startup of apprunner, a call to <tt>nsIComponentManager::AutoRegister(<i>Startup,
|
||||
<exedir>/Components</i>)</tt> This will descend recursively looking
|
||||
for loadable files (files with a certain externsion and on Mac of certain
|
||||
type) If the file had changed since the last time the file was visited
|
||||
(ModifiedDate check) registration is initiated on the file.
|
||||
<p>Registration involves:
|
||||
<ul>
|
||||
<li>
|
||||
Load the dll</li>
|
||||
|
||||
<li>
|
||||
nsIModule module = "NSGetModule"() - Create the module object</li>
|
||||
|
||||
<li>
|
||||
module->RegisterSelf(<i>location</i>)</li>
|
||||
</ul>
|
||||
|
||||
<p><br>The module registers with the componentmanager every {CLSID, ContractID}
|
||||
it implements with a call to <tt>nsIComponentManager::RegisterComponentSpec()</tt>
|
||||
These registrations are stored in the registry. Hence the next time around,
|
||||
the module is loaded not at startup but only when the first object that
|
||||
is implemented by a component in the module is created.
|
||||
<p>e.g Registration of GIF Decoder <a href="http://lxr.mozilla.org/seamonkey/source/modules/libimg/gifcom/nsGIFModule.cpp">nsGIFModule.cpp</a>
|
||||
<p><b>DO NOT CONVERT YOUR COMPONENT TO nsIModule yet. We are working on
|
||||
the sample code which will make the conversion process even simpler.</b></ul>
|
||||
|
||||
<h3>
|
||||
Module Unloading</h3>
|
||||
|
||||
<blockquote>Every module implements a CanUnload() function that returns
|
||||
a boolean of whether the module can be unloaded. This implies that the
|
||||
module needs to be counting all outstanding object and return PR_TRUE only
|
||||
if there are no outstanding objects served from within the module.
|
||||
<p>Unloading happens either on a Timer or on an explicit call to nsComponentManager::<a href="http://lxr.mozilla.org/seamonkey/ident?i=FreeLibraries">FreeLibraries()</a>.
|
||||
The general logic is:
|
||||
<ul>
|
||||
<li>
|
||||
PRBool unloadable = module->CanUnload()</li>
|
||||
|
||||
<li>
|
||||
if (unloadable && marked for unload)</li>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Unload()</li>
|
||||
</ul>
|
||||
|
||||
<li>
|
||||
if (unloadable && not mark for unload)</li>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
mark for unload</li>
|
||||
</ul>
|
||||
</ul>
|
||||
No assumptions can be made that the module will be unloaded if nsIModule::CanUnload()
|
||||
returns PR_TRUE. It is guaranteed that if nsIModule::CanUnload() returns
|
||||
PR_FALSE, the module <b>will not</b> be unloaded.</blockquote>
|
||||
|
||||
<h3>
|
||||
The Component Registry</h3>
|
||||
|
||||
<blockquote>Nothing but a persistent hiearchical store of attribute value
|
||||
pairs. It is the use of the registry by XPCOM that is very interesting.
|
||||
Physical location of the registry is in the <exedir>/component.reg
|
||||
<p>The xpcom hierarchy of the registry is considered to be opaque to components.
|
||||
Use the nsIComponentManager Api to register as opposed to meddling with
|
||||
the xpcom hierarchy in the registry directly.
|
||||
<p>mozregistry.dat is NOT the component registry. It is the application
|
||||
(apprunner) registry.</blockquote>
|
||||
|
||||
<h3>
|
||||
Old Method for Module definition</h3>
|
||||
|
||||
<blockquote>Previously module definition was scattered across many exported
|
||||
functions from a dll.
|
||||
<br> <a href="http://lxr.mozilla.org/seamonkey/ident?i=NSGetFactory">NSGetFactory(
|
||||
)</a>, <a href="http://lxr.mozilla.org/seamonkey/ident?i=NSCanUnload">NSCanUnload(
|
||||
)</a>, <a href="http://lxr.mozilla.org/seamonkey/ident?i=NSRegisterSelf">NSRegisterSelf(
|
||||
)</a>, <a href="http://lxr.mozilla.org/seamonkey/ident?i=NSUnregisterSelf">NSUnregisterSelf(
|
||||
)</a>
|
||||
<br>Now these are combined into a <a href="http://lxr.mozilla.org/seamonkey/source/xpcom/components/nsIModule.idl">nsIModule</a>
|
||||
<p><b>Please continue to use the old method until sample code using nsIModule
|
||||
is available.</b></blockquote>
|
||||
|
||||
<h3>
|
||||
ComponentManager vs ServiceManager</h3>
|
||||
|
||||
<blockquote>ServiceManager is a an object that holds instances to objects
|
||||
in a cache and manages them. It uses the ComponentManager to create an
|
||||
instance the first time an object is queried for. Lifetime of the instance
|
||||
is currently the lifetime of the app. We are working on what is required
|
||||
here and how to control the lifetime. Possbily merging ServiceManager with
|
||||
the ComponentManager.
|
||||
<p>From the components perspective there is nothing it does special to
|
||||
behave as a service. The application controls the creation of services
|
||||
by its usage or call to <tt>nsServiceManager::GetService()</tt> .Some components
|
||||
that want to enforce being a service return cached instances on <tt>nsComponentManager::CreateInstance()
|
||||
</tt>.
|
||||
We are working on a more elegant syntax and semantics for this. Post suggestions
|
||||
to newsgroup netscape.public.mozilla.xpcom (or Email <a href="mailto:mozilla-xpcom@mozilla.org">mozilla-xpcom@mozilla.org</a>)
|
||||
with suggestions.</blockquote>
|
||||
|
||||
<h3>
|
||||
ContractID vs CLSID</h3>
|
||||
|
||||
<blockquote>CLSID is a number identifying a specific implementation.
|
||||
<p>ContractID is a like a pointer to a CLSID. It is an opaque string to xpcom.It
|
||||
is used for two purposes.
|
||||
<ol>
|
||||
<li>
|
||||
Implementation independence for clients: <tt>@mozilla.org/registry;1</tt></li>
|
||||
|
||||
<br>The CLSID associating itself to a ContractID can be changed. Hence if a
|
||||
new implementation with a new CLSID superceeds an older implementation,
|
||||
the client wont be tied to the older implementation if it uses the ContractID.
|
||||
<li>
|
||||
CLSID switching: <tt>@mozilla.org/image/decoder;1?type=image/gif</tt></li>
|
||||
|
||||
<br>A client wants to create different objects based on a switch (the mimetype
|
||||
for the case of imagedecoders). A Contractid is formed with a concatenation
|
||||
of a BASE_CONTRACTID and the switch (mimetype) and an instance of that created.
|
||||
Components, when registering, associate their CLSID to specific contractids.</ol>
|
||||
NOTE: Only Clients that are adamant about the use of a specific implementation
|
||||
need to create instances using CLSID.
|
||||
<p>We encourage use of ContractID. This works well in the scriptable world
|
||||
too.
|
||||
<p><b>We are working on a ContractID syntax.</b></blockquote>
|
||||
|
||||
<h3>
|
||||
Steps for XPCOM Review</h3>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Know your interfaces and objects.</li>
|
||||
|
||||
<br>List the objects your component is serving. List the interfaces that
|
||||
it implements.
|
||||
<li>
|
||||
List the objects that your component uses.</li>
|
||||
|
||||
<li>
|
||||
<a href="http://www.mozilla.org/scriptable/interface-rules-we-break.html">http://www.mozilla.org/scriptable/interface-rules-we-break.html</a></li>
|
||||
|
||||
<li>
|
||||
Do not switch over to using nsIModule yet. We will publish sample code
|
||||
in a week with guidelines.</li>
|
||||
|
||||
<li>
|
||||
Use the above stated macros.</li>
|
||||
|
||||
<li>
|
||||
<a href="http://www.mozilla.org/projects/xpcom/">http://www.mozilla.org/projects/xpcom/</a>
|
||||
- <b>Watch for more documents here</b></li>
|
||||
</ol>
|
||||
|
||||
<p><br>
|
||||
<hr WIDTH="100%">
|
||||
<br>
|
||||
</body>
|
||||
</html>
|
@ -1,319 +0,0 @@
|
||||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="GENERATOR" content="Mozilla/4.71 [en] (X11; U; Linux 2.2.12-20 i686) [Netscape]">
|
||||
<meta name="Author" content="Suresh Duddi">
|
||||
<title>XPCOM Code FAQ</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h2>
|
||||
XPCOM Code FAQ</h2>
|
||||
Suresh Duddi <<a href="mailto:dp@netscape.com">dp@netscape.com</a>>
|
||||
<br>Last Modified: May 25 2000
|
||||
<br>
|
||||
<hr WIDTH="100%">
|
||||
<br>I am documenting things randomly as I am replying to people's questions.
|
||||
So this looks more like an FAQ.
|
||||
<h3>
|
||||
Table of Contents</h3>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
<a href="#What are the Global Objects that XPCOM maintains">What are the
|
||||
Global Objects that XPCOM maintains</a></li>
|
||||
|
||||
<li>
|
||||
<a href="#What are the static classes that XPCOM maintains">What are the
|
||||
static classes that XPCOM maintains</a></li>
|
||||
|
||||
<li>
|
||||
<a href="#Is there any restriction on which static class I should call fi">Is
|
||||
there any restriction on which static class I should call first</a></li>
|
||||
|
||||
<li>
|
||||
<a href="#What is the order of creation of the ServiceManager, ComponentM">What
|
||||
is the order of creation of the ServiceManager, ComponentManager and Registry</a></li>
|
||||
|
||||
<li>
|
||||
<a href="#Is there a global Registry being maintained">Is there a global
|
||||
Registry being maintained</a></li>
|
||||
|
||||
<li>
|
||||
<font color="#000000"><a href="#ComponentManager Vs ServiceManager">ComponentManager
|
||||
Vs ServiceManager</a></font></li>
|
||||
|
||||
<li>
|
||||
<a href="#ContractID Vs CLSID">ContractID Vs CLSID</a></li>
|
||||
|
||||
<li>
|
||||
<a href="#How to set break points in component code">How to set breakpoints
|
||||
in component code</a></li>
|
||||
|
||||
<li>
|
||||
<a href="#Generating a log from xpcom:">Generating the XPCOM LOG</a>
|
||||
<hr WIDTH="100%"></li>
|
||||
</ol>
|
||||
|
||||
<h4>
|
||||
<a NAME="What are the Global Objects that XPCOM maintains"></a>What are
|
||||
the Global Objects that XPCOM maintains</h4>
|
||||
|
||||
<ul>mGlobalServiceManager
|
||||
<br>mGlobalComponentManager</ul>
|
||||
|
||||
<h4>
|
||||
<a NAME="What are the static classes that XPCOM maintains"></a>What are
|
||||
the static classes that XPCOM maintains</h4>
|
||||
|
||||
<blockquote>nsComponentManager
|
||||
<br>nsServiceManager</blockquote>
|
||||
|
||||
<h4>
|
||||
<a NAME="Is there any restriction on which static class I should call fi"></a>Is
|
||||
there any restriction on which static class I should call first</h4>
|
||||
|
||||
<blockquote>No restrictions. You can call any function from the static
|
||||
classes nsComponentManager and nsServiceManager. XPCOM will do the right
|
||||
thing to initialize itself at both places.
|
||||
<p>Autoregistration() can happen only after Init_XPCOM() is called since
|
||||
the registy might be required by SelfRegister() functions of the dlls and
|
||||
it is only in Init_XPCOM() do we create register the RegistryFactory()
|
||||
with the ComponentManager.</blockquote>
|
||||
|
||||
<h4>
|
||||
<a NAME="What is the order of creation of the ServiceManager, ComponentM"></a>What
|
||||
is the order of creation of the ServiceManager, ComponentManager and Registry</h4>
|
||||
|
||||
<blockquote>Init_XPCOM()
|
||||
<blockquote>
|
||||
<li>
|
||||
create the global service manager</li>
|
||||
|
||||
<li>
|
||||
create the global component manager and register as service with the global
|
||||
service manager</li>
|
||||
|
||||
<li>
|
||||
RegisterFactory(...RegistryFactory...) Register the RegistryFactory
|
||||
with the component manager so that new registry objects can be created.</li>
|
||||
</blockquote>
|
||||
Now the hard problem is when to trigger Init_XPCOM() There are two static
|
||||
objects nsComponentManager and nsServiceManager. Any function in either
|
||||
of them can be called first. Today nsServiceManager::GetService() is the
|
||||
first one that gets called. All the members of the static nsServiceManager
|
||||
use the NS_GetGlobalServiceManager() to get to the global service manager.
|
||||
All members of the static nsComponentManager use the NS_GetGlobalComponentManager()
|
||||
to get to the global component manager. Hence if we trigger Init_XPCOM()
|
||||
from both NS_GetGlobalComponentManager() and NS_GetGlobalServiceManager()
|
||||
we will be safe.</blockquote>
|
||||
|
||||
<h4>
|
||||
<a NAME="Is there a global Registry being maintained"></a>Is there a global
|
||||
Registry being maintained</h4>
|
||||
|
||||
<blockquote>No. The nsIRegistry is designed to be lightweight access to
|
||||
the registry. Consumers who need to access the registry should use the
|
||||
component manager to create the their own registry access object. This
|
||||
is required because the open() call is supported by the nsIRegistry() and
|
||||
if we maintain a global registry arbitrating which registry file is opened
|
||||
is going to be a major headach.
|
||||
<p>The ContractID for the registry will be <font color="#990000">@mozilla.org/registry;1</font>
|
||||
<br> </blockquote>
|
||||
|
||||
<h4>
|
||||
<a NAME="ComponentManager Vs ServiceManager"></a><font color="#000000">ComponentManager
|
||||
Vs ServiceManager</font></h4>
|
||||
|
||||
<blockquote><font color="#000000">ComponentManager is the only way for
|
||||
component creation. ComponentManager always uses the component's factory
|
||||
to create the component instance. Clients (code that calls CreateInstance()
|
||||
to create and use a component) call the ComponentManager to create instances.
|
||||
Components (the code that implemented NSRegisterSelf()) calls the ComponentManager
|
||||
to register itself and gets called when a Client wants to instantiate a
|
||||
component.</font>
|
||||
<p><font color="#000000">ServiceManager is a convinience for getting singleton
|
||||
components, components for which only one instance stays alive for the
|
||||
entire application e.g Netlib. It enforces only one of a kind of a component
|
||||
to exist. Hence the notion of getting a service not creating one. (as opposed
|
||||
to the notion of Creating instances with the componentManager). ServiceManager
|
||||
is a convenience because components can technically force singletonism
|
||||
by making their factory return the same instance if one was created already.
|
||||
The other big use of ServiceManager is the (still unimplemented) notion
|
||||
of Shutting down a service.</font>
|
||||
<p><b><i><font color="#000000">Client</font></i></b>
|
||||
<ul>
|
||||
<li>
|
||||
<i><font color="#000000">When does a client use the service manager vs
|
||||
component manager</font></i></li>
|
||||
|
||||
<br><font color="#000000">When a client knows that the component that they
|
||||
are trying to instantiate is a singleton, they need to call service manager
|
||||
instead of component manager. Clients dont have to worry about calling
|
||||
the ComponentManager at all in this case. The ServiceManager will take
|
||||
care of creating the instance if the first one doesn't exist already.</font>
|
||||
<br>
|
||||
<li>
|
||||
<i><font color="#000000">When does a client use the Component Manager as
|
||||
opposed to Service Manager</font></i></li>
|
||||
|
||||
<br><font color="#000000">When a client wants a private instance of a component,
|
||||
they call the Component Manager. From the Clients point of view, a new
|
||||
xpcom object creation happens everytime they call CreateInstance() Anything
|
||||
else is an implementation detail that the Client need not worry about.</font>
|
||||
<br>
|
||||
<li>
|
||||
<i><font color="#000000">How does a Client know that they have to instantiate
|
||||
a singleton</font></i></li>
|
||||
|
||||
<br><font color="#000000">For now, the Client just has to know. There is
|
||||
no way of telling which component is a Service and which isn't. In fact,
|
||||
in todays xpcom (Mar 1999) any component can be accessed as a Service.
|
||||
Use your judgement until there is a proper method or service manager is
|
||||
eliminated. There is nothing even in the code that detects Services from
|
||||
Instances.</font>
|
||||
<p><b><font color="#CC0000">Need a solution for this. Email suggestion
|
||||
to <a href="mailto:warren@netscape.com,dp@netscape.com">warren@netscape.com,
|
||||
dp@netscape.com</a></font></b>
|
||||
<br> </ul>
|
||||
<b><i><font color="#000000">Component</font></i></b>
|
||||
<ul>
|
||||
<li>
|
||||
<i><font color="#000000">Can a component enforce use only as a Service</font></i></li>
|
||||
|
||||
<br><font color="#000000">No. The notion of the ServiceManager is available
|
||||
only to Clients.</font>
|
||||
<p><font color="#000000">Note that at some points when a component wants
|
||||
another component, it actually behaves as a client and hence follows the
|
||||
rules of the Client above to either CreateInstance() or GetService() the
|
||||
needed component.</font>
|
||||
<p><b><tt><font color="#990000">Workaround:</font></tt></b><font color="#000000">
|
||||
If however a component wants only one of its instances to exist and cannot
|
||||
ensure that Clients understand well enough only to use the Service Manager
|
||||
to get it, it can implement singletonism in its factory. Basically the
|
||||
factory on first instance creation should hang on to the instance. On subsequence
|
||||
instance creations, addref the instance it is holding to and return that
|
||||
instead creating a new one.</font>
|
||||
<ul>
|
||||
<br><font color="#000000">E.g preferences does this.</font> Code sample
|
||||
at
|
||||
<a href="http://lxr.mozilla.org/seamonkey/source/modules/libpref/src/nsPref.cpp#621">nsPref.cpp
|
||||
nsPrefFactory::CreateInstance()</a> and <a href="http://lxr.mozilla.org/seamonkey/source/modules/libpref/src/nsPref.cpp#227">nsPref.cpp
|
||||
nsPref::GetInstance()</a> With this implementation, whether Clients get
|
||||
to it by calling nsIServiceManager::GetService() or nsIComponentManager::CreateInstance(),
|
||||
the same object will be returned hence guaranteeing singletonism.</ul>
|
||||
|
||||
<li>
|
||||
<i><font color="#000000">Should a component do anything at creation to
|
||||
become a Service</font></i></li>
|
||||
|
||||
<br><font color="#000000">No. Again, the notion of a ServiceManager is
|
||||
available only to Clients.</font>
|
||||
<br>
|
||||
<li>
|
||||
<i><font color="#000000">Can a component advertise that it is a service
|
||||
so clients can use it as one</font></i></li>
|
||||
|
||||
<br>No. There isn't a way other than a comment in the interface of the
|
||||
header file.</ul>
|
||||
</blockquote>
|
||||
|
||||
<h4>
|
||||
<a NAME="ContractID Vs CLSID"></a>ContractID Vs CLSID</h4>
|
||||
|
||||
<blockquote>ClassID or CLSID is the unique indentification of a component.
|
||||
It is a structure of huge numbers generated by using uuidgen on a windows
|
||||
box. It is represented as a string in documentation as {108d75a0-bab5-11d2-96c4-0060b0fb9956}
|
||||
<p>ContractID is the string identification of an implementation of a component
|
||||
the client is looking for. The representation takes a URI syntax. Eg. <i>@mozilla.org/network/protocol;1?description=Http Protocol Handler&name=http</i>
|
||||
<br>Some simplify this to, ContractID is a more readable string form of a CLSID.
|
||||
That is acceptable on the periphery. The ContractID is a Client thing. Components
|
||||
register with component manager to claim that they are the implementation
|
||||
for a ContractID. A component can register to be the implementation for multiple
|
||||
ContractIDs (not implemented yet).
|
||||
<p><b><i>Client</i></b>
|
||||
<ul>
|
||||
<li>
|
||||
<i>Should CreateInstance() calls use ContractID or CLSID</i></li>
|
||||
|
||||
<br>ContractID is what Clients should use to CreateInstances. Clients should
|
||||
not even know about the CLSID unless they are hell bent on creating a particular
|
||||
implementation of a component.</ul>
|
||||
<b><i>Component</i></b>
|
||||
<ul>
|
||||
<li>
|
||||
<i>Should Components register with both a CID and ContractID</i></li>
|
||||
|
||||
<br>Absolutely.</ul>
|
||||
</blockquote>
|
||||
|
||||
<h4>
|
||||
<a NAME="How to set break points in component code"></a>How to set break
|
||||
points in component code</h4>
|
||||
|
||||
<blockquote>
|
||||
<blockquote>Since components are dynamically loaded only on demand, debugging
|
||||
them could be a hard. Here are some tips to debugging components.
|
||||
<p><b><i>Windows: VC5.0 VC6.0</i></b>
|
||||
<blockquote>Include your component library in the Project->Settings, Additional
|
||||
Dll. drop down. After that breakpoints can be enabled.</blockquote>
|
||||
<b><i>Unix: gdb</i></b>
|
||||
<blockquote>
|
||||
<ul>
|
||||
<li>
|
||||
Let the program run until you are sure that your component is loaded. Type
|
||||
Control-C. Now all symbols from your component will be available in gdb.
|
||||
Put your breakpoints and restart the app. Gdb will complain that it cannot
|
||||
set the breakpoint, and that it is temporarily disabling it, but when the
|
||||
*.so is loaded, the breakpoint is enabled automatically. - <<a href="mailto:erik@netscape.com">Eric
|
||||
Van Der Poel</a>></li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
I think typing "dir components" (assuming you're in dist/bin) will also
|
||||
allow you to see the symbols in your stack the first time. - <<a href="mailto:alecf@netscape.com">Alec
|
||||
Flett</a>></li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Using XPCOM_BREAK_ON_LOAD environment variable:</li>
|
||||
|
||||
<p><br><tt>gdb> set env XPCOM_BREAK_ON_LOAD "necko:rdf"</tt>
|
||||
<br><tt>gdb> r</tt>
|
||||
<p>This will cause xpcom to break in the debugger after loading any dll
|
||||
with substrings <tt>necko</tt> or <tt>rdf</tt> in them. At this point,
|
||||
you could instruct the debugger to load the dll symbols and set breakpoint.
|
||||
<p><tt>gdb> sha libnecko.so</tt>
|
||||
<br><tt>gdb> b nsFunctionInNecko</tt></ul>
|
||||
</blockquote>
|
||||
<b><i>Mac: Codewarrior</i></b>
|
||||
<blockquote>Just open the appropriate .xSYM file in the debugger; the debugger
|
||||
will target the library when the application is run. - <<a href="mailto:sfraser@netscape.com">Simon
|
||||
Fraser</a>></blockquote>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
<a NAME="Generating a log from xpcom:"></a><b>Generating a log from xpcom:</b>
|
||||
<blockquote>XPCOM provides log output. To enable the logging:
|
||||
<blockquote><tt>[unix]</tt>
|
||||
<br><tt>setenv NSPR_LOG_MODULES nsComponentManager:5</tt>
|
||||
<br><tt>setenv NSPR_LOG_FILE xpcom.log</tt>
|
||||
<p><tt>[win]</tt>
|
||||
<br><tt>set NSPR_LOG_MODULES=nsComponentManager:5</tt>
|
||||
<br><tt>set NSPR_LOG_FILE=xpcom.log</tt></blockquote>
|
||||
Start your application after setting the above environment variables. Debug
|
||||
log from xpcom would be in the file <tt>xpcom.log</tt></blockquote>
|
||||
|
||||
<p><br><a NAME="XPCOM Log analysis"></a><b>XPCOM Log analysis</b>
|
||||
<blockquote><a href="http://lxr.mozilla.org/seamonkey/source/xpcom/doc/xpcom-log-analyze.sh">xpcom/doc/xpcom-log-analyze.sh</a>
|
||||
is a script that does analysis of the xpcom log and prints out useful statistics
|
||||
in html format. Usage is:
|
||||
<blockquote><tt>xpcom-log-analyze.sh < xpcom.log > xpcom-log.html</tt>
|
||||
<br><tt></tt> </blockquote>
|
||||
</blockquote>
|
||||
|
||||
<hr WIDTH="100%">
|
||||
</body>
|
||||
</html>
|
@ -1,143 +0,0 @@
|
||||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="GENERATOR" content="Mozilla/4.61 [en] (X11; U; Linux 2.0.36 i686) [Netscape]">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<center>
|
||||
<h2>
|
||||
Component Loaders</h2></center>
|
||||
|
||||
<center>Brendan Eich <<a href="mailto:brendan@mozilla.org">brendan@mozilla.org</a>>
|
||||
<br>John Bandauer <<a href="mailto:jband@netscape.com">jband@netscape.com</a>>
|
||||
<br>Mike McCabe <<a href="mailto:mccabe@netscape.com">mccabe@netscape.com</a>>
|
||||
<br>Mike Shaver <<a href="mailto:shaver@mozilla.org">shaver@mozilla.org</a>>
|
||||
<br>Suresh Duddi <<a href="mailto:dp@netscape.com">dp@netscape.com</a>></center>
|
||||
|
||||
<h3>
|
||||
Scope of document</h3>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Component Developers</li>
|
||||
|
||||
<li>
|
||||
Clients of XPCOM (for information only)</li>
|
||||
</ul>
|
||||
|
||||
<h3>
|
||||
Why Component Loaders</h3>
|
||||
Currently XPCOM requires all component to be packaged in DLLs and uses
|
||||
the dynamic loading mechanism available with each platform to accomplish
|
||||
instantiation of component. This method doesn't blend well with say components
|
||||
written in java or javascript and packaged different from a DLL. Hence
|
||||
the proposal for Component Loaders.
|
||||
<br>
|
||||
<h3>
|
||||
Component Loaders</h3>
|
||||
XPCOM in its simplest form can be viewed as creating instances of objects
|
||||
given a CONTRACTID or ClassID. How it does this instantiation is specific to
|
||||
XPCOM and opaque to clients of XPCOM.
|
||||
<p>Internally XPCOM maps the passed in CONTRACTID to a CID and then the CID
|
||||
maps into a DLL name. XPCOM loads the DLL assuming the dynamic loading
|
||||
mechanism to create a factory. Then, asks the factory to create a particular
|
||||
instance. Here are roughly the steps involved:
|
||||
<ol>
|
||||
<li>
|
||||
CreateInstance(..., CONTRACTID,...)</li>
|
||||
|
||||
<li>
|
||||
Map CONTRACTID to CID</li>
|
||||
|
||||
<li>
|
||||
Map CID to DLL</li>
|
||||
|
||||
<li>
|
||||
factory = Dynamically Load DLL to create Factory</li>
|
||||
|
||||
<li>
|
||||
Use Factory to create object instance</li>
|
||||
</ol>
|
||||
The proposal for Component Loaders is to get XPCOM to delegate the loading
|
||||
to a component loader:
|
||||
<ul>
|
||||
<li>
|
||||
CreateInstance(..., CONTRACTID,...)</li>
|
||||
|
||||
<li>
|
||||
Map CONTRACTID to CID</li>
|
||||
|
||||
<li>
|
||||
<font color="#990000">Map CID to ComponentType</font></li>
|
||||
|
||||
<li>
|
||||
<font color="#990000">If ComponentType is DLL</font></li>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
factory = Dynamically Load DLL to create Factory</li>
|
||||
</ul>
|
||||
|
||||
<li>
|
||||
<font color="#990000">else</font></li>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<font color="#990000">ComponentLoaderServiceCONTRACTID = "<i>@mozilla.org/xpcom/component-loader;1?type=</i>"
|
||||
+ ComponentType <sup><a href="#* ContractID syntax might change">*</a></sup></font></li>
|
||||
|
||||
<li>
|
||||
<font color="#990000">loaderInstance = GetService(..., ComponentLoaderServiceCONTRACTID,...)</font></li>
|
||||
|
||||
<li>
|
||||
<font color="#990000">factory = loaderInstance->CreateFactory(..., componentLocation,...)</font></li>
|
||||
</ul>
|
||||
|
||||
<li>
|
||||
Use Factory to create object instance</li>
|
||||
|
||||
<h4>
|
||||
Format of ComponentType</h4>
|
||||
ComponentType is assumed to be mimetype.
|
||||
<h4>
|
||||
Component Registration</h4>
|
||||
Registration of components in DLLs wont change. ComponentType of DLL is
|
||||
assumed here. To facilitate registration of components with specifc component
|
||||
types, the component manager will provide the following API:
|
||||
<p><tt><font color="#990000">RegisterComponentWithType(const nsCID &aClass,</font></tt>
|
||||
<br><tt><font color="#990000">
|
||||
const char *aClassName,</font></tt>
|
||||
<br><tt><font color="#990000">
|
||||
const char *aContractID,</font></tt>
|
||||
<br><tt><font color="#990000">
|
||||
const char *aComponentType,</font></tt>
|
||||
<br><tt><font color="#990000">
|
||||
const char *aComponentLocation,</font></tt>
|
||||
<br><tt><font color="#990000">
|
||||
PRBool aReplace,</font></tt>
|
||||
<br><tt><font color="#990000">
|
||||
PRBool aPersist);</font></tt>
|
||||
<br>
|
||||
<br>
|
||||
<h4>
|
||||
Component Loader Service Registration</h4>
|
||||
Since the loader is just another component with a special contractid, there
|
||||
is no special registration of the component loader. Component Loaders
|
||||
use either the RegisterComponent() api if they are a DLL (most common)
|
||||
or use RegisterComponentWithType() api if they are themselves of a particular
|
||||
type (very rare).</ul>
|
||||
|
||||
<h3>
|
||||
Autoregistration of non DLL Components and Component Loaders</h3>
|
||||
<Need to figure this out>
|
||||
<br>
|
||||
<p><a NAME="* ContractID syntax might change"></a><sup><a href="#* ContractID syntax might change">*</a></sup>
|
||||
ContractID syntax might change
|
||||
<br>
|
||||
<hr WIDTH="100%">
|
||||
<br><i><font size=-1>Last Modified: 1 Aug 1999 Suresh Duddi <<a href="mailto:dp@netscape.com">dp@netscape.com</a>></font></i>
|
||||
<br>
|
||||
</body>
|
||||
</html>
|
@ -1,544 +0,0 @@
|
||||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Suresh Duddi">
|
||||
<meta name="GENERATOR" content="Mozilla/4.51 [en] (X11; U; Linux 2.0.36 i686) [Netscape]">
|
||||
<title>XPCOM Dynamic Component Registration</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<center>
|
||||
<h2>
|
||||
XPCOM Dynamic Component Registration</h2></center>
|
||||
|
||||
<center>Suresh Duddi <<a href="mailto:dp@netscape.com">dp@netscape.com</a>>
|
||||
<hr WIDTH="100%"></center>
|
||||
|
||||
<p>Dynamic object registration in XPCOM is achieved by interaction of the
|
||||
following components:
|
||||
<ul>
|
||||
<li>
|
||||
The Component Registry</li>
|
||||
|
||||
<li>
|
||||
The Repository</li>
|
||||
|
||||
<li>
|
||||
The Service Manager</li>
|
||||
|
||||
<li>
|
||||
Component dll implementing <tt>NSRegisterSelf()</tt></li>
|
||||
</ul>
|
||||
The registration mechanism for XPCOM components is similar in many ways
|
||||
to that of COM. The XPCOM component dlls will have the opportunity to register
|
||||
themselves with the registry. The exact time of installation would be either
|
||||
at install time or as a result of <b>autodetection</b> by the Repository
|
||||
Manager at runtime.
|
||||
<br>
|
||||
<hr WIDTH="100%">
|
||||
<h3>
|
||||
<a NAME="The Registry: XPCOM Hierarchy"></a>The Component Registry</h3>
|
||||
There are three types of Component Registries:
|
||||
<ol>
|
||||
<li>
|
||||
<b>App-Component-Registry<br>
|
||||
</b>Each application has its own Component Registry that lives along with
|
||||
the app in its <exe-dir>/components directory. The Component Registry
|
||||
is created on installation or first run. It is be used read-only by XPCOM</li>
|
||||
|
||||
<li>
|
||||
<b>User-Component-Registry</b></li>
|
||||
|
||||
<br>Each user can install additional components under their user home directory.
|
||||
These components will be shared across all XPCOM applications that the
|
||||
user runs.
|
||||
<li>
|
||||
<b>Meta-Component-Registry</b></li>
|
||||
|
||||
<br>Sharing Components between application: This can happen in two ways.
|
||||
The installer of an application can find the other application's components
|
||||
by looking for the application specifically and registering them with this
|
||||
app's component registry. The second and more preferable approach is to
|
||||
keep a machine wide Meta-Components-Registry that would aggregate all the
|
||||
app component registries.</ol>
|
||||
The difference component registries will be searched in the following order:
|
||||
<ol>
|
||||
<li>
|
||||
User Components Registry</li>
|
||||
|
||||
<li>
|
||||
App Component Registry</li>
|
||||
|
||||
<li>
|
||||
Meta Component Registry</li>
|
||||
</ol>
|
||||
The user component registry is the only one that will be updated on the
|
||||
fly by XPCOM. JS will be given the option to update either the App-Component-Registry
|
||||
or the User-Component-Registry and this may succeed fail based on write
|
||||
permission, although the general guideline is to update the User-Component-Registry.
|
||||
JS will have to do special things to update the App-Component-Registry.
|
||||
<p>Profiles are a notion of the app (navigator) and xpcom has nothing to
|
||||
do with it. The app will store app specific data in a Data-Registry that
|
||||
will be stored under the user's home directory.
|
||||
<h4>
|
||||
How does this Solve our problems</h4>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Multiple installations of mozilla and xpcom based apps</li>
|
||||
|
||||
<br>Since each installation is going run with their own App-Component-Registry,
|
||||
basically both apps will work. No inter process locking is essential. Since
|
||||
both processes will operate on the User-Component-Registry, inter process
|
||||
locking of the User-Component-Registry will be required.
|
||||
<li>
|
||||
Third Party components installation</li>
|
||||
|
||||
<br>Third parties can install components in their own directories and update
|
||||
the App-Component-Registry (preferable) or User-Component-Registry depending
|
||||
on if the sharing of component needs to be specific to the user or for
|
||||
all users. Facilities for updating the registry would be to use JS or write
|
||||
XPCOM code in their installer. The other option would be to add their components
|
||||
in their own directory, create a App-Component-Registry of their own in
|
||||
their directory and reference it in the Global Meta-Components-Registry.
|
||||
This will get their components used by all applications.
|
||||
<li>
|
||||
Registry used to store app specific data</li>
|
||||
|
||||
<br>This is a totally separate registry: the Data-Registry. The theory
|
||||
is that this will reside in the user's home directory. The registry hierarchy
|
||||
is app specific.
|
||||
<li>
|
||||
User Specific components</li>
|
||||
|
||||
<br>This is basically the User-Component-Registry. Inter process locking
|
||||
is required as all processes with XPCOM will access the same User-Component-Registry.
|
||||
<li>
|
||||
Embedding</li>
|
||||
|
||||
<br>This is requires more thought. The fact is when say Gecko is embedded
|
||||
into an application, Gecko is running most probably in the process space
|
||||
of that application and hence the XPCOM used will look for components in
|
||||
this embedding applications directory. The embedding procedure should create
|
||||
a App-Component-Reqistry for the embedding application that should contain
|
||||
all the components from different apps this app would like to use. This
|
||||
is however not required, if the Meta-Component-Registry exists.
|
||||
<li>
|
||||
User not having permission to the place where the global registry lives,
|
||||
if there is one.</li>
|
||||
|
||||
<br>First the App-Component-Registry is written to only when there is a
|
||||
new component or a component has gone away. New components come with installers
|
||||
or the user calls regFactory.exe with the dll as an argument or clicks
|
||||
on a button that says "refresh my user components" which will cause autoregistration
|
||||
of user components. For deleted app components, annotations will be made
|
||||
in the User-Component-Registry. Deleted user components is a non-issue.
|
||||
<li>
|
||||
NFS mounted home directories and app directories</li>
|
||||
|
||||
<br>NFS mounted home directories requires inter-machine locking of the
|
||||
User-Component-Registry. NFS mounted app directories dont have a
|
||||
problem as the App-Component-Registry is only used read-only by XPCOM.</ol>
|
||||
So in summary,
|
||||
<ul>
|
||||
<li>
|
||||
App-Component-Registry pretty much solves the top problem of Multiple applications.
|
||||
With some help from the installer, Third party components will also be
|
||||
solved.</li>
|
||||
|
||||
<li>
|
||||
User-Component-Registry solves the User Specific Components problem.</li>
|
||||
|
||||
<li>
|
||||
Meta-Component-Registry enables the dynamic sharing of components between
|
||||
apps which eases embedding.</li>
|
||||
</ul>
|
||||
As a first cut, I am going to implement the App-Component-Registry for
|
||||
M8.
|
||||
<h4>
|
||||
Hierarchy Used by Component Registry</h4>
|
||||
XPCOM uses the nsRegistry to store mappings between CLSIDs and their implementations.
|
||||
The Registry provides persistent storage of hierarchical keys and name-value
|
||||
pairs associated with each key. Each key also keeps a default value.
|
||||
<p>XPCOM will use the following registry hierarchy:
|
||||
<blockquote><tt>ROOTKEY_COMMON</tt>
|
||||
<br><tt> Common</tt>
|
||||
<br><tt> Classes</tt>
|
||||
<br><tt>
|
||||
CLSID</tt>
|
||||
<br><tt>
|
||||
<b><font color="#CC0000">{108d75a0-bab5-11d2-96c4-0060b0fb9956}</font></b></tt>
|
||||
<br><tt><nobr>
|
||||
InprocServer (S) = <font color="#CC0000">/home/dp/dist/bin/components/libnfs-protocol.so</font></nobr></tt>
|
||||
<br><tt><nobr>
|
||||
ContractID (S) = <b><font color="#CC0000">@mozilla.org/network-protocol;1?type=nfs</font></b></nobr></tt>
|
||||
<br><tt><nobr>
|
||||
ClassName (S) = <b><font color="#CC0000">NFS Protocol
|
||||
Handler</font></b></nobr></tt>
|
||||
<p><tt> <font color="#CC0000">@mozilla.org/network-protocol;1?type=nfs</font></tt>
|
||||
<br><tt><nobr>
|
||||
CLSID (S) = <font color="#CC0000">{108d75a0-bab5-11d2-96c4-0060b0fb9956}</font></nobr></tt>
|
||||
<p><tt><i> </i>Software</tt>
|
||||
<br><tt> Netscape</tt>
|
||||
<br><tt>
|
||||
XPCOM</tt>
|
||||
<br><tt>
|
||||
VersionString (S)
|
||||
= <font color="#CC0000">alpha0.20</font></tt>
|
||||
<p><tt>
|
||||
<font color="#CC0000">/home/dp/dist/bin/components/libnfs-protocol.so</font></tt>
|
||||
<br><tt>
|
||||
ComponentsCount (Int) = <font color="#CC0000">1</font></tt>
|
||||
<br><tt>
|
||||
FileSize (Int)
|
||||
= <font color="#CC0000">78965</font></tt>
|
||||
<br><tt>
|
||||
LastModTimeStamp (S) = <font color="#CC0000">Wed
|
||||
Feb 24 11:24:06 PST 1999</font></tt>
|
||||
<p><tt><font color="#CC0000">
|
||||
</font><font color="#000000">Events</font></tt>
|
||||
<br><tt><font color="#000000">
|
||||
Startup</font></tt>
|
||||
<br><tt><font color="#000000">
|
||||
</font><font color="#CC0000">{108d75a0-bab5-11d2-96c4-0060b0fb9956}</font></tt>
|
||||
<br><tt><font color="#CC0000">
|
||||
{17894983-ab78-8d75-a0bb-511d296c4006}</font></tt>
|
||||
<p><tt><font color="#000000">
|
||||
Shutdown</font></tt>
|
||||
<br><tt><font color="#000000">
|
||||
</font><font color="#CC0000">{748958ea-abab-511d-296c-40060b0fb995}</font></tt>
|
||||
<br><tt><font color="#CC0000">
|
||||
{45617894-983a-b788-d75a-0bab11d296c4}</font></tt>
|
||||
<br> </blockquote>
|
||||
|
||||
<h3>
|
||||
|
||||
<hr WIDTH="100%"><a NAME="The Repository: Object instance creation"></a>The
|
||||
Repository: Object instance creation</h3>
|
||||
All object creation happens via The Repository. <tt>nsIRepository::CreateInstance()</tt>
|
||||
will be the primary way of creation of object instances. The steps in instantiation
|
||||
of an object that implements the IID interface and of class CLSID is as
|
||||
follows:
|
||||
<ol>
|
||||
<li>
|
||||
The CLSID of the component that would need to create the object instance
|
||||
is identified.</li>
|
||||
|
||||
<ol>Callers use <tt>nsIRepository::ContractIDToCLSID()</tt> to convert the
|
||||
ContractID string to the CLSID.</ol>
|
||||
|
||||
<li>
|
||||
Load the dll associated with the CLSID after consulting the Registry</li>
|
||||
|
||||
<li>
|
||||
Instantiate the class factory by calling a globally exported dll function
|
||||
<tt>NSGetFactory()</tt>.
|
||||
This returns an instance of the class factory that implements the <tt>nsIFactory</tt>
|
||||
interface.</li>
|
||||
|
||||
<li>
|
||||
The actual object creation is delegated to this <tt>nsIFactory</tt> instance
|
||||
with a call to <tt>nsIFactory::CreateInstance()</tt>.</li>
|
||||
</ol>
|
||||
|
||||
<h3>
|
||||
|
||||
<hr WIDTH="100%"><a NAME="The Service Manager"></a>The Service Manager</h3>
|
||||
All globally created system services are available via the <tt>nsIServiceManager</tt>,
|
||||
including the <tt>nsIRepository</tt> and <tt>nsIRegistry</tt>. Although
|
||||
the <tt>nsIServiceManager</tt> uses the Registry and Repository in the
|
||||
creation and maintenance of other services, the circular dependency is
|
||||
broken by not letting the <tt>nsIServiceManager</tt> create the <tt>nsIRepository</tt>
|
||||
and <tt>nsIRegistry</tt> instance and registering them specially with the
|
||||
<tt>nsIServiceManager</tt>.
|
||||
The nsIServiceManager is passed into NSGetFactory() for assisting the DLL
|
||||
in the Factory creation process.
|
||||
<h3>
|
||||
|
||||
<hr WIDTH="100%"><a NAME="Component Registration"></a>Component Registration</h3>
|
||||
Either at installation time of the Component or at times when the XPCOM
|
||||
library autodetect new/changed dlls, component registration is activated.
|
||||
The autodetection happens at startup time of the navigator or via a javascript
|
||||
trigger <tt>navigator.repository.autodetect()</tt>. The steps in component
|
||||
registration would be:
|
||||
<ol>
|
||||
<li>
|
||||
The dll is loaded</li>
|
||||
|
||||
<li>
|
||||
The component is allowed to self register by a call to a globally exported
|
||||
dll function <tt>NSRegisterSelf()</tt>. The <tt>nsIServiceManager</tt>
|
||||
and the fullpath of the dll are passed in to assist in the registration
|
||||
process. The dll is expected to create/modify its entries in the Registry
|
||||
according to the guidelines of the <a href="#The Registry: XPCOM Hierarchy">XPCOM
|
||||
hierarchy</a> in the registry. <tt>nsIRepository</tt>, which can be queried
|
||||
from the <tt>nsIServiceManager</tt>, has useful registration functions
|
||||
that would easen the process.</li>
|
||||
|
||||
<li>
|
||||
The dll is unloaded</li>
|
||||
</ol>
|
||||
|
||||
<h3>
|
||||
|
||||
<hr WIDTH="100%"><a NAME="Autodetection of Components"></a>Autodetection
|
||||
of Components</h3>
|
||||
Autodetection of changed dlls happened by storing the dll's last modified
|
||||
time and its size in the Registry automatically. If either the last modified
|
||||
time stamp or the filesize differs from that stored in the Registry for
|
||||
the dll, re-registration takes place. Before re-registration, the existing
|
||||
instances of the objects created by the classes in the dll are not freed
|
||||
because the <tt>nsIRepository</tt> has no list of them. The <tt>NSCanUnload()</tt>
|
||||
will be called with input parameter <i>force</i> set to <tt>true</tt>.
|
||||
The dll has to prepare for getting unloaded. After this call returns, the
|
||||
dll <b>will</b> be unloaded if the return value is <tt>true</tt>. If the
|
||||
dll detects that it cannot properly prepare for unloading, then it can
|
||||
return <tt>false</tt>. XPCOM will not let the re-registration of the modified
|
||||
dll proceed in this case. There is nothing much that XPCOM library can
|
||||
do to salvage this situation other than warning the user of possible instability
|
||||
and advice a restart upon which the re-registration will happen.
|
||||
<h3>
|
||||
|
||||
<hr WIDTH="100%"><a NAME="ContractID Spec"></a>ContractID Spec</h3>
|
||||
The general format of ContractIDs is <i><b><font color="#990000">@</font></b>mozilla.org<b><font color="#990000">/</font></b>compname<b><font color="#990000">&</font>version</b><b><font color="#990000">?</font></b>var<b><font color="#990000">=</font></b>value<b><font color="#990000">&</font></b>var<b><font color="#990000">=</font></b>value<b><font color="#990000">&</font></b>var<b><font color="#990000">=</font></b>value...</i>
|
||||
<p>Let us consider some more examples:
|
||||
<ol>
|
||||
<li>
|
||||
A pluggable protocol that implementes the nfs protocol</li>
|
||||
|
||||
<li>
|
||||
A converter that can handle application/x-zip</li>
|
||||
|
||||
<li>
|
||||
A plugin that can handle image/gif</li>
|
||||
|
||||
<li>
|
||||
A widget that can do a toolbar</li>
|
||||
|
||||
<li>
|
||||
A datasource that can handle mail</li>
|
||||
|
||||
<li>
|
||||
A helperapp that deals with application/postscript</li>
|
||||
</ol>
|
||||
All the above have what type they are and one or more arguments on what
|
||||
they particularly do.
|
||||
<p>The ContractID for these would look like
|
||||
<ol>
|
||||
<li>
|
||||
<tt>@mozilla.org/network-protocol;1?type=nfs</tt></li>
|
||||
|
||||
<li>
|
||||
<tt>@mozilla.org/data-converter;1?type=application/x-zip</tt></li>
|
||||
|
||||
<li>
|
||||
<tt>@mozilla.org/plugin;1?description=Renders GIF Images....&name=ImageMedia Gif Image Plugin&type=image/gif</tt></li>
|
||||
|
||||
<li>
|
||||
<tt>@mozilla.org/widget;1?type=toolbar</tt></li>
|
||||
|
||||
<li>
|
||||
<tt>@mozilla.org/rdf/datsource;1?type=mail</tt></li>
|
||||
|
||||
<li>
|
||||
<tt>@mozilla.org/helperapp;1?type=application/postscript</tt></li>
|
||||
</ol>
|
||||
{Assume proper escaping of all above URI}
|
||||
<p>The above semantics would let ContractID be an extensible mechanism that
|
||||
could be searched on multiple ways. And
|
||||
<br>query on a contractid should match only whatever was passed in. So a query
|
||||
for
|
||||
<br>@mozilla.org/plugin;1?type=image/gif should pass for the contractid
|
||||
specified above. We could extend this
|
||||
<br>mechanism with wildcards, but I dont want to go there yet... :-)
|
||||
<br>
|
||||
<h3>
|
||||
|
||||
<hr WIDTH="100%"><a NAME="Startup Components"></a>Components created on
|
||||
events</h3>
|
||||
<b><font color="#990000">NOTE: THIS IS NOT BEING DONE. We are going to
|
||||
expect the apps to this themselves by using the registry.</font></b>
|
||||
<p>Some dlls have components that want to be created on certain events
|
||||
namely Startup, Shutdown (for now). Example is xpinstall.
|
||||
<blockquote>RegisterComponentForEvent(..., RegisterationTime when, ...)
|
||||
<br>RegisterFactoryForEvent(..., RegistrationTime when,...)</blockquote>
|
||||
exists for this purpose. When an application wants to Fire the particular
|
||||
event, it calls
|
||||
<blockquote>nsComponentManager::FireEvent(RegistrationTime when)</blockquote>
|
||||
ComponentManager will look for components that are registered to be created
|
||||
on these events and do the following for each of the components:
|
||||
<ol>
|
||||
<li>
|
||||
CreateInstance(...,CID, knsIStartupComponentIID, &obj);</li>
|
||||
|
||||
<br>For a shutdown event, knsIShutdownComponentIID would be used.
|
||||
<br>
|
||||
<li>
|
||||
obj->Release();</li>
|
||||
|
||||
<br>The component needs to take adequate measures to keep itself alive
|
||||
and figure out how it would delete the object, since a Release() happens
|
||||
immediately after a CreateInstace()</ol>
|
||||
<b><i>Warning: </i></b>Order of creation of multiple components registered
|
||||
on the same event is not defined. Component dependencies aren't thought
|
||||
of yet.
|
||||
<br>
|
||||
<h3>
|
||||
|
||||
<hr WIDTH="100%"><a NAME="How will all this help me"></a>How will all this
|
||||
help me</h3>
|
||||
For Component Developers:
|
||||
<ul>
|
||||
<li>
|
||||
Component dlls developed could be dropped into a directory, a JS function
|
||||
called after which your component is in business without even a restart
|
||||
of the browser. Of course, there needs to be someone accessing it.</li>
|
||||
|
||||
<li>
|
||||
No need to export you CLSID or run around finding where to advertise your
|
||||
CLSID</li>
|
||||
</ul>
|
||||
For Component Users:
|
||||
<blockquote>
|
||||
<li>
|
||||
No more hacking in calls to <tt>nsIRepository::RegisterFactory()</tt></li>
|
||||
|
||||
<li>
|
||||
No need to know the CLSID of components that you want to instantiate. Component
|
||||
creation can happen like this</li>
|
||||
|
||||
<br><tt>nsIRepository::CreateInstance(<b>"<font color="#CC0000">@mozilla.org/network-protocol;1?type=nfs</font>"</b>,
|
||||
NULL, kProtocolIID, &result);</tt>
|
||||
<br>instead of
|
||||
<br><strike>nsIRepository::CreateInstance(NFS_PROTOCOL_CID, NULL, domIID,
|
||||
&result);</strike></blockquote>
|
||||
|
||||
<h3>
|
||||
|
||||
<hr WIDTH="100%"><a NAME="What has happened so far"></a>What has happened
|
||||
so far</h3>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Autoregistration implemented to grovel for components from the current
|
||||
directory</li>
|
||||
|
||||
<li>
|
||||
nsRepository is a global object. Not nsIRepository exists.</li>
|
||||
|
||||
<li>
|
||||
nsRepository::ContractIDToCLSID() implemented</li>
|
||||
</ul>
|
||||
|
||||
<h3>
|
||||
|
||||
<hr WIDTH="100%"><a NAME="Changes to XPCOM happening"></a>Changes to XPCOM
|
||||
happening</h3>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
API changes to get ContractID in entire registration process for factories
|
||||
and components</li>
|
||||
|
||||
<li>
|
||||
ContractID cache to improve performance of ContractID queries</li>
|
||||
|
||||
<li>
|
||||
Notion of Component dlls living in a <b>Components directory </b>and autoregistration
|
||||
will load/manage only these components. Other components that are linked
|
||||
in to the app need to call <tt>nsRepository::RegisterFactory()</tt> from
|
||||
the app. <b>To make this happen we need a list of these.</b></li>
|
||||
|
||||
<li>
|
||||
<b>nsRegistry:</b> Enabling the new nsRegistry developed by Bill Law <law@netscape.com></li>
|
||||
|
||||
<li>
|
||||
Service Manager and Repository: Merge them</li>
|
||||
|
||||
<li>
|
||||
Convenience function to createIntance(contractid)</li>
|
||||
|
||||
<li>
|
||||
Base ContractID in the interface ID header file</li>
|
||||
</ul>
|
||||
|
||||
<h3>
|
||||
|
||||
<hr WIDTH="100%"><a NAME="What should I do"></a>What should I do</h3>
|
||||
|
||||
<ul><b><font color="#CC0000">Component Developers</font></b>
|
||||
<ul>
|
||||
<li>
|
||||
<font color="#000000">Implement <tt>NSRegisterSelf()</tt> for your component
|
||||
dlls. Sample implementation that perf</font>
|
||||
<a href="http://lxr.mozilla.org/mozilla/source/modules/libpref/src/nsPref.cpp#608">http://lxr.mozilla.org/mozilla/source/modules/libpref/src/nsPref.cpp#608</a></li>
|
||||
|
||||
<li>
|
||||
Use <tt>nsRepository::RegisterComponent()</tt> instead of <tt>nsRepository::RegisterFactory()</tt>
|
||||
if your component lives in a DLL</li>
|
||||
|
||||
<li>
|
||||
<b>Dont use static constructors in loadable components</b></li>
|
||||
</ul>
|
||||
|
||||
<p><br><b><font color="#CC0000">Component Users</font></b>
|
||||
<ul>
|
||||
<li>
|
||||
Create all your components using ContractID rather than CID</li>
|
||||
|
||||
<li>
|
||||
If you were thinking of managing creation of components yourself, think
|
||||
again. The repository may be already doing that.</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<h3>
|
||||
|
||||
<hr WIDTH="100%"><a NAME="Issues"></a>Issues</h3>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Need support for questions like:</li>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Enumerate all CLSIDs that implement a particular interface.</li>
|
||||
|
||||
<li>
|
||||
Let a particular CLSID be the preferable implementation for an interface.</li>
|
||||
|
||||
<br>I dont know how this a XPCOM component user could use it unless there
|
||||
could be a call like:
|
||||
<br><tt>nsIRepository::CreateInstance(<b>NULL</b>, NULL, nsWidgetIID, &result);</tt>
|
||||
<li>
|
||||
Enumerate all interfaces supported by a CLSID</li>
|
||||
</ol>
|
||||
|
||||
<li>
|
||||
Resolving naming conflicts between ContractID</li>
|
||||
|
||||
<li>
|
||||
Store component specific name-values under <tt>ROOTKEY_COMMON\\<i>component.class.version\\</i></tt></li>
|
||||
|
||||
<li>
|
||||
Add a registry entry under <tt>ROOTKEY_COMMON\\<i>component.class.version\\</i></tt>to
|
||||
indicate the willingness for a CLSID to behave as a Service.</li>
|
||||
|
||||
<li>
|
||||
Add quick registration support functions in <tt>nsIRepository</tt> for
|
||||
components to use.</li>
|
||||
|
||||
<li>
|
||||
Is the hierarchy <tt>ROOTKEY_COMMON\\<b>Classes</b>\\CLSID </tt>acceptable.</li>
|
||||
|
||||
<li>
|
||||
Should we have a nsIRepository. JS needs it so that they can reflect it
|
||||
in javascript. Remove &'s in the API.</li>
|
||||
</ul>
|
||||
|
||||
<hr WIDTH="100%">
|
||||
<br><i><font size=-1>Last Modified: 28 Jan 1998</font></i>
|
||||
<br><font size=-1><i>Feedback to: </i><a href="news:netscape.public.mozilla.xpcom">netscape.public.mozilla.xpcom</a></font>
|
||||
</body>
|
||||
</html>
|
@ -1,208 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
# Perl script to analyze the log output from xpcom and print
|
||||
# the results in html.
|
||||
#
|
||||
# To get the xpcom log output to a file say xpcom.log:
|
||||
# setenv NSPR_LOG_MODULES nsComponentManager:5
|
||||
# setenv NSPR_LOG_FILE xpcom.log
|
||||
# ./mozilla
|
||||
# <quit>
|
||||
#
|
||||
# To get registry (used to figure out contractid mappings)
|
||||
# ./regExport component.reg > registry.txt
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# a) To get simple output
|
||||
# cat xpcom.log | perl xpcom-log-analyze.pl > xpcom-log.html
|
||||
#
|
||||
# b) To get all possible cid->contractid mappings filled in
|
||||
# cat xpcom.log registry.txt | perl xpcom-log-analyze.pl > xpcom-log.html
|
||||
#
|
||||
#
|
||||
# Author: Suresh Duddi <dp@netscape.com>
|
||||
# Created Aug 9 2000
|
||||
|
||||
while (<>)
|
||||
{
|
||||
chomp;
|
||||
if ( /ContractIDToClassID.*\}/ )
|
||||
{
|
||||
# Passed contractid to cid mapping. Add contractid to cid mapping
|
||||
$cid = GetCID();
|
||||
$contractid = GetContractID();
|
||||
$contractid_map{$cid} = $contractid;
|
||||
$contractid_passed{$contractid}++;
|
||||
$ncontractid_passed++;
|
||||
next;
|
||||
}
|
||||
|
||||
if ( /ContractIDToClassID.*FAILED/ )
|
||||
{
|
||||
# Failed contractid. Collect it.
|
||||
$contractid = GetContractID();
|
||||
$contractid_failed{$contractid}++;
|
||||
$ncontractid_failed++;
|
||||
next;
|
||||
}
|
||||
|
||||
if ( /CreateInstance.*succeeded/ )
|
||||
{
|
||||
# Successful create instance
|
||||
$objects{GetCID()}++;
|
||||
$nobjects++;
|
||||
next;
|
||||
}
|
||||
|
||||
if ( /CreateInstance.*FAILED/ )
|
||||
{
|
||||
# Failed create instance
|
||||
$objects_failed{GetCID()}++;
|
||||
$nobjects_failed++;
|
||||
next;
|
||||
}
|
||||
|
||||
if ( /: loading/ )
|
||||
{
|
||||
$dll = GetDll();
|
||||
# make the name a little pretty
|
||||
$dll =~ s/^.*bin\///;
|
||||
$dll_loaded[@dll_loaded] = $dll;
|
||||
next;
|
||||
}
|
||||
|
||||
if ( / classID - \{/ )
|
||||
{
|
||||
# this is from the output of registry. Try to update contractid_map
|
||||
$cid = GetCID();
|
||||
# Get the next contractid or classname line until a empty new line
|
||||
$_ = <STDIN> until (/ContractID|ClassName/ || length == 1);
|
||||
chomp;
|
||||
$contractid = $_;
|
||||
$contractid =~ s/^.*= //;
|
||||
$contractid_map{$cid} = $contractid;
|
||||
}
|
||||
}
|
||||
|
||||
PrintHTMLResults();
|
||||
|
||||
|
||||
sub GetContractID() {
|
||||
# Get a proid from a line
|
||||
my($contractid) = $_;
|
||||
$contractid =~ s/^.*\((.*)\).*$/$1/;
|
||||
# print "Got Progid: $contractid\n";
|
||||
return $contractid;
|
||||
}
|
||||
|
||||
sub GetCID() {
|
||||
# Get a CID from a line
|
||||
my($cid) = $_;
|
||||
$cid =~ s/^.*\{(.*)\}.*$/$1/;
|
||||
# print "Got cid: $cid\n";
|
||||
return $cid;
|
||||
}
|
||||
|
||||
sub GetDll() {
|
||||
# Get a Dll from a line
|
||||
my($dll) = $_;
|
||||
$dll =~ s/^.*\"(.*)\".*$/$1/;
|
||||
# print "Got dll: $dll\n";
|
||||
return $dll;
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Print the results of our log analysis in html
|
||||
#
|
||||
sub PrintHTMLResults()
|
||||
{
|
||||
$now_time = localtime();
|
||||
print "<HTML><HEAD><title>XPCOM Log analysis dated: $now_time\n";
|
||||
print "</TITLE></HEAD>\n";
|
||||
print "<H1><center>\n";
|
||||
print "XPCOM Log analysis dated: $now_time\n";
|
||||
print "</center></H1>\n";
|
||||
# ========================================================================
|
||||
# Performance analysis
|
||||
# ========================================================================
|
||||
print "<H2>Performance Analysis</H2>\n";
|
||||
|
||||
# Number of dlls loaded
|
||||
$n = @dll_loaded;
|
||||
print "<H3>Dlls Loaded : $n</H3>\n";
|
||||
print "<blockquote><pre>\n";
|
||||
PrintArray(@dll_loaded);
|
||||
print "</blockquote></pre>\n";
|
||||
|
||||
# Objects created with a histogram
|
||||
print "<H3>Objects created : $nobjects</H3>\n";
|
||||
print "<blockquote><pre>\n";
|
||||
@sorted_key = SortKeyByValue(%objects);
|
||||
foreach $cid (@sorted_key)
|
||||
{
|
||||
printf("%5d %s [%s]\n", $objects{$cid}, $cid, $contractid_map{$cid});
|
||||
}
|
||||
print "</blockquote></pre>\n";
|
||||
|
||||
# Passed contractid calls
|
||||
print "<H3>Succeeded ContractIDToClassID() : $ncontractid_passed</H3>\n";
|
||||
print "<blockquote><pre>\n";
|
||||
@sorted_key = SortKeyByValue(%contractid_passed);
|
||||
foreach $contractid (@sorted_key)
|
||||
{
|
||||
printf("%5d %s\n", $contractid_passed{$contractid}, $contractid);
|
||||
}
|
||||
print "</blockquote></pre>\n";
|
||||
|
||||
|
||||
# ========================================================================
|
||||
# Error analysis
|
||||
# ========================================================================
|
||||
print "<H2>Error Analysis</H2>\n";
|
||||
|
||||
# CreateInstance() FAILED
|
||||
print "<H3>Failed CreateInstance() : $nobjects_failed</H3>\n";
|
||||
print "<blockquote><pre>\n";
|
||||
@sorted_key = SortKeyByValue(%objects_failed);
|
||||
foreach $cid (@sorted_key)
|
||||
{
|
||||
printf("%5d %s [%s]\n", $objects_failed{$cid}, $cid, $contractid_map{$cid});
|
||||
}
|
||||
print "</blockquote></pre>\n";
|
||||
|
||||
# ContractIDToClassID() FAILED with a histogram
|
||||
print "<H3>Failed ContractIDToClassID() : $ncontractid_failed</H3>\n";
|
||||
print "<blockquote><pre>\n";
|
||||
@sorted_key = SortKeyByValue(%contractid_failed);
|
||||
foreach $contractid (@sorted_key)
|
||||
{
|
||||
printf("%5d %s\n", $contractid_failed{$contractid}, $contractid);
|
||||
}
|
||||
print "</blockquote></pre>\n";
|
||||
|
||||
# end the html listing
|
||||
print "</HTML>\n";
|
||||
}
|
||||
|
||||
|
||||
sub PrintArray()
|
||||
{
|
||||
my(@array) = @_;
|
||||
for ($i=0; $i<@array; $i++)
|
||||
{
|
||||
print "$array[$i]\n";
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Sort a given hash by reverse numeric order of value
|
||||
# return the sorted keylist
|
||||
#
|
||||
sub SortKeyByValue()
|
||||
{
|
||||
my(%hash) = @_;
|
||||
my(@sorted_keys) = sort { $hash{$b} <=> $hash{$a} } keys %hash;
|
||||
return @sorted_keys;
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Shell script to analyze the xpcom log file
|
||||
#
|
||||
# Usage: xpcom-log-analize.sh [<logfile>] > xpcom-log.html
|
||||
#
|
||||
# You can generate the xpcom log file using:
|
||||
# setenv NSPR_LOG_MODULES nsComponentManager:5
|
||||
# setenv NSPR_LOG_FILE xpcom.log
|
||||
# ./mozilla
|
||||
# <quit>
|
||||
#
|
||||
# Contributors:
|
||||
# Suresh Duddi <dp@netscape.com>
|
||||
# Vamsee Nalagandla <vamsee9@hotmail.com>
|
||||
#
|
||||
|
||||
if [ $# -gt 0 ]
|
||||
then
|
||||
logfile=$1
|
||||
else
|
||||
logfile=xpcom.log
|
||||
fi
|
||||
|
||||
# make sure we got the logfile
|
||||
if [ ! -f $logfile ]
|
||||
then
|
||||
echo "Error: Cannot find xpcom logfile $logfile"
|
||||
exit -1
|
||||
fi
|
||||
|
||||
echo "<HTML>"
|
||||
echo "<HEAD>"
|
||||
echo "<TITLE>XPCOM Log analysis dated:"
|
||||
date
|
||||
echo "</TITLE></HEAD>"
|
||||
echo "<H1><center>"
|
||||
echo "XPCOM Log analysis dated:"
|
||||
date
|
||||
echo "</center></H1>"
|
||||
# ========================================================================
|
||||
# Performance analysis
|
||||
# ========================================================================
|
||||
echo "<H2>Performance Analysis</H2>"
|
||||
|
||||
# Number of dlls loaded
|
||||
n=`grep -i ': loading' ${logfile} | wc -l`
|
||||
echo "<H3>Dlls Loaded : $n</H3>"
|
||||
echo "<blockquote><pre>"
|
||||
grep ': loading' $logfile
|
||||
echo "</pre></blockquote>"
|
||||
|
||||
# Objects created with a histogram
|
||||
n=`grep -i 'createinstance.*succeeded' ${logfile} | wc -l`
|
||||
echo "<H3>Objects created : $n</H3>"
|
||||
echo "<blockquote><pre>"
|
||||
grep -i 'createinstance.*succeeded' ${logfile} | sort | uniq -c | sort -nr
|
||||
echo "</pre></blockquote>"
|
||||
|
||||
# Number of RegisterFactory
|
||||
n=`grep 'RegisterFactory' $logfile | wc -l`
|
||||
echo "<H3>Factory registrations : $n</H3>"
|
||||
echo "<blockquote><pre>"
|
||||
grep 'RegisterFactory' $logfile
|
||||
echo "</pre></blockquote>"
|
||||
|
||||
# Number of RegisterComponentCommon.
|
||||
# XXX Order them by dllname
|
||||
n=`grep 'RegisterComponentCommon({' $logfile | wc -l`
|
||||
echo "<H3>Component Registrations : $n</H3>"
|
||||
echo "<blockquote><pre>"
|
||||
grep 'RegisterComponentCommon({' $logfile
|
||||
echo "</pre></blockquote>"
|
||||
|
||||
# Number of succeeded calls to ContractIDToClassID() with histogram
|
||||
n=`grep -i 'contractidtoclassid.*}' $logfile | wc -l`
|
||||
echo "<H3>Count of succeeded ContractIDToClassID() : $n</H3>"
|
||||
echo "<blockquote><pre>"
|
||||
grep -i 'contractidtoclassid.*}' $logfile | sort | uniq -c | sort -nr
|
||||
echo "</pre></blockquote>"
|
||||
|
||||
|
||||
# ========================================================================
|
||||
# Error analysis
|
||||
# ========================================================================
|
||||
echo "<H2>Error Analysis</H2>"
|
||||
|
||||
# CreateInstance() FAILED
|
||||
n=`grep 'CreateInstance.*FAILED' $logfile | wc -l`
|
||||
echo "<H3>Failed CreateInstance() : $n</H3>"
|
||||
echo "<blockquote><pre>"
|
||||
grep 'CreateInstance.*FAILED' $logfile
|
||||
echo "</pre></blockquote>"
|
||||
|
||||
# ContractIDToClassID() FAILED with a histogram
|
||||
n=`grep 'ContractIDToClassID.*FAILED' $logfile | wc -l`
|
||||
echo "<H3>Failed ContractIDToClassID() : $n</H3>"
|
||||
echo "<blockquote><pre>"
|
||||
grep 'ContractIDToClassID.*FAILED' $logfile | sort | uniq -c | sort -nr
|
||||
echo "</pre></blockquote>"
|
||||
|
||||
#
|
||||
# Cleanup
|
||||
echo "</HTML>"
|
@ -1,142 +0,0 @@
|
||||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Suresh Duddi">
|
||||
<meta name="GENERATOR" content="Mozilla/4.71 [en] (X11; U; Linux 2.2.12-20 i686) [Netscape]">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<center>
|
||||
<h2>
|
||||
Standalone XPCOM v 0.5</h2></center>
|
||||
|
||||
<center>Version 0.5
|
||||
<br>15 May 2000
|
||||
<br>Suresh Duddi <dp@netscape.com>
|
||||
<hr WIDTH="100%"></center>
|
||||
|
||||
<h3>
|
||||
1.0 Overview</h3>
|
||||
Standalone XPCOM is a tree configuration, that when built, provides a minimal
|
||||
set of libraries (shared mostly) that can be used to get all features of
|
||||
XPCOM. The contents of this standalone XPCOM in general are:
|
||||
<ul>
|
||||
<li>
|
||||
NSPR : mozilla/nsprpub</li>
|
||||
|
||||
<li>
|
||||
Registry : mozilla/modules/libreg</li>
|
||||
|
||||
<li>
|
||||
XPCOM : mozilla/xpcom</li>
|
||||
</ul>
|
||||
<b>NOTE 1: xpcom apis are not frozen yet. By XPCOM 1.0 release they will
|
||||
be.</b>
|
||||
<br><b>NOTE 2: xpcom standalone differs from the xpcom built with mozilla.
|
||||
Hence cannot be used with the mozilla browser.</b>
|
||||
<h3>
|
||||
2.0 Building Standalone XPCOM</h3>
|
||||
Here are the instructions for building the Standalone XPCOM on Unix or Windows:
|
||||
<br>
|
||||
<ol><b>Step 1 : Pull the sources</b>
|
||||
<li>
|
||||
<tt>cvs -z 3 co mozilla/client.mk</tt></li>
|
||||
|
||||
<li>
|
||||
<tt>cd mozilla</tt></li>
|
||||
|
||||
<li>
|
||||
<tt>gmake -f client.mk pull_all BUILD_MODULES=xpcom</tt></li>
|
||||
</ol>
|
||||
|
||||
<ol><b>Step 2 : Build XPCOM Standalone</b>
|
||||
<li>
|
||||
<tt>configure --enable-standalone-modules=xpcom</tt></li>
|
||||
|
||||
<li>
|
||||
<tt>gmake</tt></li>
|
||||
</ol>
|
||||
<h3>
|
||||
3.0 Testing Standalone XPCOM</h3>
|
||||
<tt>xpcom/sample</tt> contains a sample application and a component. This
|
||||
should get built by default.
|
||||
<ul>
|
||||
<li>
|
||||
<tt>nsTestSample</tt> is the sample application. This should have been
|
||||
installed in your <tt>bin/</tt> directory.</li>
|
||||
|
||||
<li>
|
||||
<tt>libsample.so (unix) </tt>is the sample component implementation that
|
||||
the sample application will try to instantiate. This should have been installed
|
||||
in your <tt>bin/components</tt> directory</li>
|
||||
</ul>
|
||||
To run the test,
|
||||
<ol>
|
||||
<li>
|
||||
cd to your <tt>bin/</tt> directory</li>
|
||||
|
||||
<li>
|
||||
setenv LD_LIBRARY_PATH .</li>
|
||||
|
||||
<li>
|
||||
<tt>./nsTestSample</tt></li>
|
||||
|
||||
<br><tt>Warning: MOZILLA_FIVE_HOME not set.</tt>
|
||||
<br><tt>nsNativeComponentLoader: autoregistering begins.</tt>
|
||||
<br><tt>nsNativeComponentLoader: autoregistering succeeded</tt>
|
||||
<br><tt>Inital print: initial value</tt>
|
||||
<br><tt>Set value to: XPCOM defies gravity</tt>
|
||||
<br><tt>Final print : XPCOM defies gravity</tt>
|
||||
<br><b><tt>Test passed.</tt></b></ol>
|
||||
|
||||
<h3>
|
||||
4.0 Test FAILED: What went wrong ?</h3>
|
||||
The most common case of why the sample would have failed if you didn't
|
||||
run it from the bin directory. Here are some error messsages and possible
|
||||
ways of fixing them.
|
||||
<ol>
|
||||
<li>
|
||||
<b><tt>./nsTestSample: error in loading shared libraries: libxpcom.so:
|
||||
cannot open shared object file: No such file or directory</tt></b></li>
|
||||
|
||||
<ol>LD_LIBRARY_PATH not set. To fix "<tt>setenv LD_LIBRARY_PATH ."</tt></ol>
|
||||
|
||||
<li>
|
||||
<b>Link errors when building xpcom standalone</b></li>
|
||||
|
||||
<ol>This is mostly due to the fact that probably xpcom is not being built
|
||||
standalone. Make sure you did "<tt>configure --enable-standalone-modules=xpcom"</tt></ol>
|
||||
</ol>
|
||||
|
||||
<h3>
|
||||
5.0 Whats the difference between Standalone and non-Standalone XPCOM</h3>
|
||||
|
||||
There is no binary difference between standalone XPCOM and the XPCOM that ships with the Mozilla browser. The one functional difference is that XPT files cannot be read from .zip files in standalone XPCOM.
|
||||
<h3>
|
||||
6.0 TODO for v 1.0</h3>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Optional exclusion of specific features into standalone XPCOM like
|
||||
registry, xpconnect. Tweeking these options will cause reduction
|
||||
in memory requirements and size.</li>
|
||||
|
||||
<li>
|
||||
Get <tt>xpcom/tests</tt> directory upto date and documented.</li>
|
||||
|
||||
<li>
|
||||
Update this document for Mac.</li>
|
||||
|
||||
<li>
|
||||
API freeze and documentation</li>
|
||||
</ol>
|
||||
|
||||
<h3>
|
||||
7.0 Future (post v 1.0)</h3>
|
||||
mmh! let me think...
|
||||
<p>
|
||||
<hr WIDTH="100%">
|
||||
<br>Suresh Duddi <dp@netscape.com>
|
||||
</body>
|
||||
</html>
|
@ -1,161 +0,0 @@
|
||||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="pnunn">
|
||||
<meta name="GENERATOR" content="Mozilla/4.5 [en]C-NSCP (WinNT; U) [Netscape]">
|
||||
<title>xpCom FAQ</title>
|
||||
</head>
|
||||
<body>
|
||||
<b><font size=+3>XPCOM FAQ</font></b>
|
||||
<p>Get out your decoder rings kids!
|
||||
<p>Having a basic understanding of COM is only the first
|
||||
<br>step. To get CMonkey code to build and run,
|
||||
<br>you need to translate your COM ideas into Netscape
|
||||
<br>speak.
|
||||
<p>Feel free to add to this document or change incorrect info.
|
||||
<br>Hopefully more info and more examples will help new
|
||||
<br>people reach XPCOM nirvana more quickly.
|
||||
<p><b>To mentally translate XPCOM to COM.</b>
|
||||
<br>
|
||||
<table BORDER COLS=2 WIDTH="100%" >
|
||||
<tr>
|
||||
<td BGCOLOR="#CCCCCC"><b>vanilla COM</b></td>
|
||||
|
||||
<td BGCOLOR="#FFCCCC"><b>XPCOM</b></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td BGCOLOR="#CCCCCC"> IUnknown</td>
|
||||
|
||||
<td BGCOLOR="#FFCCCC">nsISupports</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td BGCOLOR="#CCCCCC">IClassFactory</td>
|
||||
|
||||
<td BGCOLOR="#FFCCCC">nsIFactory</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td BGCOLOR="#CCCCCC">virtual void _stdcall</td>
|
||||
|
||||
<td BGCOLOR="#FFCCCC">NS_IMETHOD</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td BGCOLOR="#CCCCCC">interface ID = IID</td>
|
||||
|
||||
<td BGCOLOR="#FFCCCC">nsID = nsIID = IID</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td BGCOLOR="#CCCCCC">class ID = CLSID </td>
|
||||
|
||||
<td BGCOLOR="#FFCCCC">nsCID = CID</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>Not too difficult.
|
||||
<br>But wait. There's more.
|
||||
<br><b>-------------------------------------------</b>
|
||||
<p><b><font size=+1>Why don't those classes have AddRef?</font></b>
|
||||
<p>Actually, those classes do have AddRef. It is hidden
|
||||
<br>in a macro. There are alot of macros that are alot of help
|
||||
<br>once you know :
|
||||
<br> 1) They exist.
|
||||
<p> 2) Where they are defined. (They aren't always mnemonic
|
||||
or onomatipeic.
|
||||
<br>
|
||||
You might want to print them out.)
|
||||
<p> mozilla/xpcom/public/nsCom.h
|
||||
<br>
|
||||
mozilla/xpcom/public/nsISupports.h
|
||||
<p> 3)What they are
|
||||
<br>
|
||||
Here's a short list to give you an idea of what you've been missing.
|
||||
<br>
|
||||
The include files listed above are the real reference.
|
||||
<p> 4) A quick way to expand pesky macros:
|
||||
<br>
|
||||
For macros in foo.cpp, 'make foo.i'
|
||||
<p> This
|
||||
will pump the foo.cpp file through C preprocessing
|
||||
<br>
|
||||
and expand all the macros for you. The output can be
|
||||
<br>
|
||||
hard to read, but if you search for unique strings
|
||||
<br>
|
||||
in the area you aredebugging, you can navigate
|
||||
<br>
|
||||
the file pretty easily.
|
||||
<br>
|
||||
(thanks to hshaw@netscape.com)
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<table BORDER COLS=2 WIDTH="100%" BGCOLOR="#CCCCCC" >
|
||||
<tr>
|
||||
<td BGCOLOR="#FFCCCC"><b><font size=+1>Netscape MACRO</font></b></td>
|
||||
|
||||
<td><b><font size=+1>Expansion of macro</font></b></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td BGCOLOR="#FFCCCC">NSADDREF(factoryinstname)</td>
|
||||
|
||||
<td>Factory->AddRef();</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td BGCOLOR="#FFCCCC">NS_IMETHOD</td>
|
||||
|
||||
<td>virtual nsresult __stdcall</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td BGCOLOR="#FFCCCC">NS_INIT_REFCNT()</td>
|
||||
|
||||
<td>mRefCnt = 0</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td BGCOLOR="#FFCCCC">NS_INIT_ISUPPORTS()</td>
|
||||
|
||||
<td>NS_INIT_REFCNT()</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td BGCOLOR="#FFCCCC">NS_DECL_ISUPPORTS</td>
|
||||
|
||||
<td>public:
|
||||
<br> NS_IMETHOD QueryInterface(REFNSIID
|
||||
aIID,
|
||||
<br>
|
||||
void** aInstancePtr);
|
||||
<br> NS_IMETHOD_(nsrefcnt)
|
||||
AddRef(void);
|
||||
<br> NS_IMETHOD_(nsrefcnt)
|
||||
Release(void);
|
||||
<br> protected:
|
||||
<br> nsrefcnt mRefCnt;</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p> <font size=+1>Useful Links to COM Documents:</font>
|
||||
<p><a href="http://www.mozilla.org/projects/xpcom/">XPCOM Page</a>
|
||||
<br><a href="http://www.mozilla.org/projects/xpcom/nsCOMPtr.html">nsCOMPtr</a>
|
||||
<br><a href="http://warp.netscape.com/client/raptor/codingconventions.html">Coding
|
||||
Conventions</a>
|
||||
<br><a href="http://warp/client/bam/eng/howto.html">Getting BAMmed</a>
|
||||
<br><a href="http://warp/client/bam/eng/comdoc.html">How to COM</a>
|
||||
<br><a href="http://www.mozilla.org/docs/tplist/catFlow/modunote.htm">Modularization
|
||||
Techniques</a>
|
||||
<br><a href="http://www.mozilla.org/docs/tplist/catBuild/portable-cpp.html">C++
|
||||
Portability Guide</a>
|
||||
<br><a href="http://www.mozilla.org/newlayout/">NGLayout</a>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
</body>
|
||||
</html>
|
Loading…
x
Reference in New Issue
Block a user