зеркало из https://github.com/mozilla/pjs.git
preliminary documentation for nsIClassInfo
This commit is contained in:
Родитель
c05ae96710
Коммит
bc42cad066
|
@ -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 <<a href="mailto:shaver@mozilla.org">shaver@mozilla.org</a>
|
||||
><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<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="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>
|
||||
<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>
|
Загрузка…
Ссылка в новой задаче