preliminary documentation for nsIClassInfo

This commit is contained in:
shaver%mozilla.org 2001-03-08 02:32:20 +00:00
Родитель c05ae96710
Коммит bc42cad066
1 изменённых файлов: 150 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,150 @@
<!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 &lt;<a href="mailto:shaver@mozilla.org">shaver@mozilla.org</a>
&gt;<br>
Last Modified: March 7, 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="#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&lt;nsIClassInfo&gt; 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="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> &nbsp; {<br>
&nbsp; &nbsp; "Sample Component", NS_SAMPLE_CID, NS_SAMPLE_CONTRACTID,
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br>
&nbsp; &nbsp; nsSampleImplConstructor,</code><br>
<code> &nbsp; &nbsp; nsSampleRegistrationProc,</code><br>
<code> &nbsp; &nbsp; nsSampleUnregistrationProc,</code><br>
<code> &nbsp; &nbsp; nsnull /* no factory destructor */,</code><br>
<code><font color="#ff0000"> &nbsp; &nbsp; NS_CI_INTERFACE_GETTER_NAME(nsSampleImpl),&nbsp;
/* interface getter */</font></code><br>
<code> &nbsp; &nbsp; nsnull /* no language helper */,</code><br>
<code><font color="#ff0000"> &nbsp; &nbsp; &amp;NS_CLASSINFO_NAME(nsSampleImpl),&nbsp;
/* global class-info pointer */</font></code><br>
<code> &nbsp; &nbsp; 0 /* no class flags */<br>
&nbsp; }</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>
<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.</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
working on that, too.
<h4><a name="Whats_interface_flattening"></a>What's "interface
flattening"?</h4>
<p>You'd think that you might find an explanation of interface
flattening in <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=13422">
bug 13422</a> , but you'd be wrong. I'll need to write one here.<br>
<br>
</p>
<br>
<br>
<br>
</body>
</html>