Frequently Asked Questions

  • Revision slug: Using_nsCOMPtr/Frequently_Asked_Questions
  • Revision title: Frequently Asked Questions
  • Revision id: 99636
  • Created:
  • Creator: Yoshino
  • Is current revision? No
  • Comment divide the doc into pages

Revision Content

This section will help you if you're fixing a broken build, or have what you think is a quick obvious question, and you don't have time to read the {{mediawiki.external('#reference_manual Reference Manual')}}. This FAQ usually just refers back directly to the appropriate answer, there. If you're looking here just to learn about nsCOMPtrs, you'll get a better introduction in the {{mediawiki.external('#users_guide Getting Started Guide')}}.

The FAQ is divided into sections to help you find what you're looking for faster. In most cases, the answer will just refer back into the reference manual, above. No need to explain things twice :-).

Buildtime Errors

The build just broke. It's not in your code, or it's not on your platform, but there's an nsCOMPtr on the line where the error is and you're suspicious. You're looking in the right place.

comparing an nsCOMPtr to a raw [XP]COM interface pointer

declaring an nsCOMPtr to a forward-declared class

not linking to XPCOM

not including nsCOMPtr.h

different settings of NSCAP_FEATURE_DEBUG_PTR_TYPES

Runtime Errors

NS_ASSERTION "QueryInterface needed"

NS_PRECONDITION "You can't dereference a NULL nsCOMPtr with operator->()"

NS_PRECONDITION "You can't dereference a NULL nsCOMPtr with operator*()"

How do I...

initialize an nsCOMPtr?

Release an nsCOMPtr before it goes out of scope?

Assign 0 into it. Whenever an nsCOMPtr takes on a new value, it always Releases its old value, if any. Assigning in the value 0 is just like assigning in a raw pointer that happens to be NULL. The old referent will be Released. [See {{mediawiki.external('#ref_assignment Initialization and Assignment')}} for more details]

You should note, though, that there is a small performance penalty for this. The nsCOMPtr will still exercize logic in its destructor to attempt to Release the value it has at that time. The optimal solution is to arrange the lifetime of your nsCOMPtr to correspond to exactly how long you want to hold the reference. E.g., using blocks as in this sample

// The most efficient scheme is to scope your |nsCOMPtr| to live exactly as long
//  as you need to hold the reference

nsresult
SomeLongFunction( nsIBar* aBar )
  {
    nsresult rv;
    // ...

    {
      // I only need the |nsIFoo| interface for a short time
      //  so I control its lifetime by declaring it inside
      //  a block statement.

      nsCOMPtr<nsIFoo> foo( do_QueryInterface(aBar, &rv) );
      if ( foo )
        foo->DoSomeFooThing();

      // |foo| goes out of scope, and so |Release|s its referent, here
    }

    // ...tons of stuff here, during which I don't need an |nsIFoo|

    return rv;
  }

[[Move this discussion to the {{mediawiki.external('#ref_efficiency efficiency section')}}, and link to it from here.]]

make an nsCOMPtr leak (for a debug test)?

call a getter that uses a raw [XP]COM interface pointer as an `in/out' parameter?

call a getter that fills in an nsIFoo*& parameter?

call a getter that doesn't AddRef its result?

Any {{mediawiki.external('XP')}}COM function that returns an interface pointer, i.e., a `getter', must have already AddRefed that pointer. If it didn't, you should probably report it as a bug. No matter which code pattern you use to solve this problem, you should comment it, e.g., // Warning: this getter doesn't AddRef() its result. If the getter returns the new pointer as its function result, no worries,


General

Does nsCOMPtr bloat the code?

Are nsCOMPtrs fast? Can I use them in tight loops?

Bibliography

Web Resources

nsCOMPtr.h, and nsCOMPtr.cpp are the source to nsCOMPtr. You can examine the source to nsCOMPtr online using (the wonderful) LXR. Exploring this code is not an adventure for the faint of heart.

Some COM Ownership Guidelines.

Interface Pointers Considered Harmful by Don Box originally appeared in the September 1995 issue of "The C++ Report".

COM Smart Pointers Even More Harmful by Don Box is a follow-up article that originally appeared in the February 1996 issue of "The C++ Report".

Books

Essential COM by Don Box.

Effective COM by Don Box, et al.

The C++ Programming Language (3rd Edition) by Bjarne Stroustrup.

Effective C++ (2nd Edition): 50 Specific Ways to Improve Your Programs and Designs by Scott Meyers.

More Effective C++ : 35 New Ways to Improve Your Programs and Designs by Scott Meyers.

Effective C++ CD: 85 Specific Ways to Improve Your Programs and Designs by Scott Meyers.

People

Don Box is a smart guy who has been writing about COM programming for a long time.

Revision Source

<p>
</p><p>This section will help you if you're fixing a broken build, or have what you think is a quick obvious question, and you don't have time to read the {{mediawiki.external('#reference_manual Reference Manual')}}. This FAQ usually just refers back directly to the appropriate answer, there. If you're looking here just to learn about <code>nsCOMPtr</code>s, you'll get a better introduction in the {{mediawiki.external('#users_guide Getting Started Guide')}}.
</p><p>The FAQ is divided into sections to help you find what you're looking for faster. In most cases, the answer will just refer back into the reference manual, above. No need to explain things twice <code><span class="plain">:-)</span></code>.
</p>
<h3 name="Buildtime_Errors"> Buildtime Errors </h3>
<p>The build just broke. It's not in your code, or it's not on your platform, but there's an <code>nsCOMPtr</code> on the line where the error is and you're suspicious. You're looking in the right place.
</p>
<h4 name="comparing_an_nsCOMPtr_to_a_raw_.5BXP.5DCOM_interface_pointer"> comparing an <code>nsCOMPtr</code> to a raw [XP]COM interface pointer </h4>
<h4 name="declaring_an_nsCOMPtr_to_a_forward-declared_class"> declaring an <code>nsCOMPtr</code> to a forward-declared class </h4>
<h4 name="not_linking_to_XPCOM"> not linking to XPCOM </h4>
<h4 name="not_including_nsCOMPtr.h"> not including nsCOMPtr.h </h4>
<h4 name="different_settings_of_NSCAP_FEATURE_DEBUG_PTR_TYPES"> different settings of <code>NSCAP_FEATURE_DEBUG_PTR_TYPES</code> </h4>
<h3 name="Runtime_Errors"> Runtime Errors </h3>
<h4 name="NS_ASSERTION_.22QueryInterface_needed.22"> <code>NS_ASSERTION</code> "QueryInterface needed" </h4>
<h4 name="NS_PRECONDITION_.22You_can.27t_dereference_a_NULL_nsCOMPtr_with_operator-.3E.28.29.22"> <code>NS_PRECONDITION</code> "You can't dereference a NULL nsCOMPtr with operator-&gt;()" </h4>
<h4 name="NS_PRECONDITION_.22You_can.27t_dereference_a_NULL_nsCOMPtr_with_operator.2A.28.29.22"> <code>NS_PRECONDITION</code> "You can't dereference a NULL nsCOMPtr with operator*()" </h4>
<h3 name="How_do_I..."> How do I... </h3>
<h4 name="initialize_an_nsCOMPtr.3F"> initialize an <code>nsCOMPtr</code>? </h4>
<h4 name="Release_an_nsCOMPtr_before_it_goes_out_of_scope.3F"> <code>Release</code> an <code>nsCOMPtr</code> before it goes out of scope? </h4>
<p>Assign <code>0</code> into it. Whenever an <code>nsCOMPtr</code> takes on a new value, it always <code>Release</code>s its old value, if any. Assigning in the value <code>0</code> is just like assigning in a raw pointer that happens to be <code>NULL</code>. The old referent will be <code>Release</code>d. [See {{mediawiki.external('#ref_assignment Initialization and Assignment')}} for more details]
</p><p>You should note, though, that there is a small performance penalty for this. The <code>nsCOMPtr</code> will still exercize logic in its destructor to attempt to <code>Release</code> the value it has at that time. The optimal solution is to arrange the lifetime of your <code>nsCOMPtr</code> to correspond to exactly how long you want to hold the reference. E.g., using blocks as in this sample
</p>
<table>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// The most efficient scheme is to scope your |nsCOMPtr| to live exactly as long</span>
<span class="comment">//  as you need to hold the reference</span>

nsresult
SomeLongFunction( nsIBar* aBar )
  {
    nsresult rv;
    <span class="comment">// ...</span>

    {
      <span class="comment">// I only need the |nsIFoo| interface for a short time</span>
      <span class="comment">//  so I control its lifetime by declaring it inside</span>
      <span class="comment">//  a block statement.</span>

      nsCOMPtr&lt;nsIFoo&gt; foo( do_QueryInterface(aBar, &amp;rv) );
      if ( foo )
        foo-&gt;DoSomeFooThing();

      <span class="comment">// |foo| goes out of scope, and so |Release|s its referent, here</span>
    }

    <span class="comment">// ...tons of stuff here, during which I don't need an |nsIFoo|</span>

    return rv;
  }
</pre>
</td></tr></tbody></table>
<div class="editor-note">
<p><span class="plain"> [[Move this discussion to the </span>{{mediawiki.external('#ref_efficiency efficiency section')}}, and link to it from here.]]
</p>
</div>
<h4 name="make_an_nsCOMPtr_leak_.28for_a_debug_test.29.3F"> make an <code>nsCOMPtr</code> leak (for a debug test)? </h4>
<h4 name="call_a_getter_that_uses_a_raw_.5BXP.5DCOM_interface_pointer_as_an_.60in.2Fout.27_parameter.3F"> call a getter that uses a raw [XP]COM interface pointer as an `in/out' parameter? </h4>
<h4 name="call_a_getter_that_fills_in_an_nsIFoo.2A&amp;_parameter.3F"> call a getter that fills in an <code>nsIFoo*&amp;</code> parameter? </h4>
<h4 name="call_a_getter_that_doesn.27t_AddRef_its_result.3F"> call a getter that doesn't <code>AddRef</code> its result? </h4>
<p>Any {{mediawiki.external('XP')}}COM function that returns an interface pointer, i.e., a `getter', must have already <code>AddRef</code>ed that pointer. If it didn't, you should probably report it as a bug. No matter which code pattern you use to solve this problem, you should comment it, e.g., <code><span class="comment">// Warning: this getter doesn't AddRef() its result</span></code>. If the getter returns the new pointer as its function result, no worries,
</p>
<table>
<tbody><tr>
<td>
<p><br> 
</p>
</td></tr></tbody></table>
<h3 name="General"> General </h3>
<h4 name="Does_nsCOMPtr_bloat_the_code.3F"> Does <code>nsCOMPtr</code> bloat the code? </h4>
<h4 name="Are_nsCOMPtrs_fast.3F_Can_I_use_them_in_tight_loops.3F"> Are <code>nsCOMPtr</code>s fast? Can I use them in tight loops? </h4>
<h3 name="Bibliography"> Bibliography </h3>
<h4 name="Web_Resources"> Web Resources </h4>
<div class="biblio-entry">
<p><span class="doc-title"><a class="external" href="http://lxr.mozilla.org/seamonkey/source/xpcom/glue/nsCOMPtr.h">nsCOMPtr.h</a></span>, and <span class="doc-title"><a class="external" href="http://lxr.mozilla.org/seamonkey/source/xpcom/glue/nsCOMPtr.cpp">nsCOMPtr.cpp</a></span> are the source to <code>nsCOMPtr</code>. You can examine the source to <code>nsCOMPtr</code> online using (the wonderful) <a class="external" href="http://lxr.mozilla.org/">LXR</a>. Exploring this code is not an adventure for the faint of heart.
</p>
</div>
<div class="biblio-entry">
<p><span class="doc-title"><a class="external" href="http://www.mozilla.org/projects/xpcom/Ownership.html">Some COM Ownership Guidelines</a></span>.
</p>
</div><div class="biblio-entry">
<p><span class="doc-title"><a class="external" href="http://www.develop.com/dbox/cxx/InterfacePtr.htm">Interface Pointers Considered Harmful</a></span> by Don Box originally appeared in the September 1995 issue of "The C++ Report".
</p>
</div><div class="biblio-entry">
<p><span class="doc-title"><a class="external" href="http://www.develop.com/dbox/cxx/SmartPtr.htm">COM Smart Pointers Even More Harmful</a></span> by Don Box is a follow-up article that originally appeared in the February 1996 issue of "The C++ Report".
</p>
</div>
<h4 name="Books"> Books </h4>
<div class="biblio-entry">
<p><span class="doc-title"><a class="external" href="http://www.amazon.com/exec/obidos/ASIN/0201634465">Essential COM</a></span> by Don Box.
</p>
</div>
<div class="biblio-entry">
<p><span class="doc-title"><a class="external" href="http://www.amazon.com/exec/obidos/ASIN/0201379686">Effective COM</a></span> by Don Box, et al.
</p>
</div>
<div class="biblio-entry">
<p><span class="doc-title"><a class="external" href="http://www.amazon.com/exec/obidos/ASIN/0201889544">The C++ Programming Language (3rd Edition)</a></span> by Bjarne Stroustrup.
</p>
</div>
<div class="biblio-entry">
<p><span class="doc-title"><a class="external" href="http://www.amazon.com/exec/obidos/ASIN/0201924889">Effective C++ (2nd Edition): 50 Specific Ways to Improve Your Programs and Designs</a></span> by Scott Meyers.
</p>
</div>
<div class="biblio-entry">
<p><span class="doc-title"><a class="external" href="http://www.amazon.com/exec/obidos/ASIN/020163371X">More Effective C++ : 35 New Ways to Improve Your Programs and Designs</a></span> by Scott Meyers.
</p>
</div>
<div class="biblio-entry">
<p><span class="doc-title"><a class="external" href="http://www.amazon.com/exec/obidos/ASIN/0201310155">Effective C++ CD: 85 Specific Ways to Improve Your Programs and Designs</a></span> by Scott Meyers.
</p>
</div>
<h4 name="People"> People </h4>
<div class="biblio-entry">
<p><span class="doc-title"><a class="external" href="http://www.develop.com/dbox/">Don Box</a></span> is a smart guy who has been writing about COM programming for a long time.
</p>
</div>
Revert to this revision