16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<!-- ***** BEGIN LICENSE BLOCK *****
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync - The contents of this file are subject to the Mozilla Public License Version
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync - 1.1 (the "License"); you may not use this file except in compliance with
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync - the License. You may obtain a copy of the License at
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync - Software distributed under the License is distributed on an "AS IS" basis,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync - for the specific language governing rights and limitations under the
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync - The Original Code is PyXPCOM.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync - The Initial Developer of the Original Code is
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync - ActiveState Tool Corporation.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync - Portions created by the Initial Developer are Copyright (C) 2000-2001
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync - the Initial Developer. All Rights Reserved.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync - Contributor(s):
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync - Alternatively, the contents of this file may be used under the terms of
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync - either the GNU General Public License Version 2 or later (the "GPL"), or
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync - in which case the provisions of the GPL or the LGPL are applicable instead
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync - of those above. If you wish to allow use of your version of this file only
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync - under the terms of either the GPL or the LGPL, and not to allow others to
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync - use your version of this file under the terms of the MPL, indicate your
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync - decision by deleting the provisions above and replace them with the notice
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync - and other provisions required by the LGPL or the GPL. If you do not delete
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync - the provisions above, a recipient may use your version of this file under
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync - the terms of any one of the MPL, the GPL or the LGPL.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync - ***** END LICENSE BLOCK ***** -->
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<meta name="ProgId" content="FrontPage.Editor.Document">
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<p>This is a quick introduction to the Python XPCOM Package. We assume that you have a good understanding of Python and <a href="http://www.mozilla.org/projects/xpcom/">XPCOM</a>,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncand have experience both using and implementing XPCOM objects in some other
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsynclanguage (e.g., C++ or JavaScript). We <b><i>do not</i></b> attempt to
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncprovide a tutorial to XPCOM or Python itself, only to using Python <i>and</i>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<p>This tutorial contains the following sections:</p>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync <li><a href="#Using">Using XPCOM Objects and Interfaces</a> - when you wish to
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync <i>use</i> a component written by anyone else in any XPCOM supported
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync language.</li>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync <li><a href="#Implementing">Implementing XPCOM Objects and Interfaces</a> -
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync when you wish to implement a component for use by anyone else in any xpcom
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync supported language.</li>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync <li><a href="#Parameters">Parameters and Types</a> - useful information
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync regarding how Python translates XPCOM types, and handles byref parameters.</li>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<p>For anything not covered here, try the <a href="advanced.html">advanced
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncdocumentation</a>, and if that fails, use the source, Luke!</p>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<h2><a name="Using">Using XPCOM object and interfaces.</a></h2>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<p>The techniques for using XPCOM in Python have been borrowed from JavaScript -
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncthus, the model described here should be quite familiar to existing JavaScript
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncXPCOM programmers.</p>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<p>When using an XPCOM object, the primary module used is the <u><i>xpcom.components</i></u>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync module. Using this module, you can get a Python object that supports any
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncscriptable XPCOM interface. Once you have this Python object, you can
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncsimply call XPCOM methods on the object, as normal.</p>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<p>The <u><i>xpcom.components</i></u> module defines the following public
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncmembers:</p>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync <td width="84%">A mapping (dictionary-like object) used to get XPCOM
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync "classes". These are indexed by XPCOM contract ID, just
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync like the JavaScript object of the same name.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync <pre>cls = components.classes["@mozilla.org/sample;1"]
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncob = cls.createInstance() # Now have an nsISupports</pre>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync <td width="84%">An object that exposes all XPCOM interface IDs (IIDs).
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync Like the JavaScript object of the same name, this object uses
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync "dot" notation, as demonstrated below.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync <pre>ob = cls.createInstance(components.interfaces.nsISample)
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync# Now have an nsISample</pre>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<p>For many people, this is all you need to know. Consider the Mozilla Sample Component. The Mozilla Sample
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncComponent has a contract ID of <i>@mozilla.org/sample;1</i>,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<p>Thus, a complete Python program that uses this component is shown below.</p>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<pre>from xpcom import components
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsynccls = components.classes["@mozilla.org/sample;1"]
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncob = cls.createInstance() # no need to specify an IID for most components
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync# nsISample defines a "value" property - let's use it!
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncob.value = "new value"
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncif ob.value != "new value":
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync print "Eeek - what happened?"</pre>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<p>And that is it - a complete Python program that uses XPCOM.</p>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<h2><a name="Implementing">Implementing XPCOM Objects and Interfaces.</a></h2>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<p>Implementing XPCOM objects is almost as simple as using them. The
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncbasic strategy is this:</p>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync <li>Create a standard Python source file, with a standard Python class.</li>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync <li>Add some special <a href="#Attributes"> attributes</a> to your class for use by the Python XPCOM
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync framework. This controls the XPCOM behavior of your object.</li>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync <li>Implement the XPCOM <a href="#Properties"> properties</a> and methods of your classes as normal.</li>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync <li>Put the Python source file in the Mozilla <i> components</i> directory.</li>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<p>There are two classes of attributes: those used at runtime to define the object
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncbehavior and those used at registration time to control object
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncregistration. Not all objects require registration, thus not all
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncPython XPCOM objects will have registration-related attributes.</p>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync <td width="83%">The interface IDs (IIDs) supported by the component.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync For simplicity, this may be either a single IID, or a list of IIDs.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync There is no need to specify base interfaces, as all parent interfaces are
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync automatically supported. Thus, it is never necessary to nominate <i>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync nsISupports</i> in the list of interfaces.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync <p>This attribute is required. Objects without such an attribute are
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync deemed unsuitable for use as a XPCOM object.</td>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync <td width="83%">The contract ID of the component. Required if the
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync component requires registration (i.e., exists in the components directory).</td>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync <td width="83%">The Class ID (CLSID) of the component, as a string in the
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync standard "{XXX-XXX-XXX-XXX}" format. Required if the
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync component requires registration (i.e., exists in the components directory).</td>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync <td width="83%">Nominates a function that is called at registration
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync time. The default is for no extra function to be called. This can
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync be useful if a component has special registration requirements and needs
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync to hook into the registration process.</td>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync <td width="83%">The description of the XPCOM object. This may be used by
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync browsers or other such objects. If not specified, the contract ID
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync is used.</td>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<p>A Python class can support XPCOM properties in one of two ways. Either
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsynca standard Python property of the same name can exist - our sample
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsynccomponent demonstrates this with the <i>boolean_value</i> property.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncAlternatively, the class can provide the <i>get_propertyName(self)</i> and <i>set_propertyName(self,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncvalue)</i> functions (with <i>propertyName</i> changed to the appropriate value for the
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncproperty), and these functions will be called instead.</p>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<h4>Example: The Python XPCOM Test Component</h4>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<p>As an example, examine the Python XPCOM Test Component. This
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsynccode can be found in <i>py_test_component.py</i>.</p>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<pre>from xpcom import components
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncclass PythonTestComponent:
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync _com_interfaces_ = components.interfaces.nsIPythonTestInterface
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync _reg_clsid_ = "{7EE4BDC6-CB53-42c1-A9E4-616B8E012ABA}"
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync _reg_contractid_ = "Python.TestComponent"
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync def __init__(self):
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync def do_boolean(self, p1, p2):
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync ret = p1 ^ p2
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync return ret, not ret, ret
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<p><b>Note:</b> This component only specifies the mandatory attributes - <i>_com_interfaces</i>,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<p>This sample code demonstrates supporting the <i>boolean_value</i> attribute,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncsupported implicitly, as it is defined in the IDL and exists as a real Python
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncattribute of that name, and a method called <i>do_boolean</i>.</p>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<p> The xpcom/xpt.py script is a useful script that can generate the skeleton of a class for
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncany XPCOM interface. Just specify the interface name on the command-line,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncand paste the output into your source file.</p>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<p>This is the output of running this program over the <i>nsISample</i>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncinterface (i.e., assuming we wanted to implement a component that supported this
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncinterface):</p>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<pre>class nsISample:
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync _com_interfaces_ = xpcom.components.interfaces.nsISample
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync # If this object needs to be registered, the following 2 are also needed.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync # _reg_clsid_ = {a new clsid generated for this object}
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync # _reg_contractid_ = "The.Object.Name"
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync def get_value( self ):
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync # Result: string
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync def set_value( self, param0 ):
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync # Result: void - None
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync # In: param0: string
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync def writeValue( self, param0 ):
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync # Result: void - None
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync # In: param0: string
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync def poke( self, param0 ):
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync # Result: void - None
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync # In: param0: string
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<p><b>Note:</b> The types of the parameters and the function itself are included in
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncthe comments. You need to implement the functions
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncthemselves. Another advantage of this script is that the <a href="#HiddenParams">hidden
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncparameters</a> are handled for you; the comments indicate when parameters
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsynchave been hidden.</p>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<h2><a name="Parameters">Parameters and Types</a></h2>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<p>This section briefly describes the XPCOM type support in
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<p>All XPCOM interfaces define parameters of a specific type. There is
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsynccurrently no concept of a variant, or union of all types. Thus, the
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncconversion rules are very straightforward, and generally surprise free: for
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncany given XPCOM method, there is only one possible type for a given parameter.</p>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync <li>All numeric types will attempt to be coerced to the correct type.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync Thus, you can pass a Python float to an XPCOM method expecting an integer,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync or vice-versa. Specifically, when an integer is required, you can pass
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync any Python object for which <i>int()</i> would succeed; for a Python float,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync any object for which <i>float()</i> would succeed is acceptable. This
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync means that you can pass a Python string object as an integer, as long as the
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync string was holding a valid integer.</li>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync <li>Strings and Unicode objects are interchangeable, but no other automatic
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync string conversions are performed. Thus, you can not pass an integer
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync where a string is expected, even though the reverse is true.</li>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync <li>Any sequence object can be passed as an array. List objects are
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync always returned for arrays.</li>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync <li>Any Python instance suitable for use as a XPCOM object (i.e., with the
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync <a href="#Implementing">necessary annotations</a>) can be
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync passed as a XPCOM object. No special wrapping step is needed to turn a
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync Python instance into a XPCOM object. Note you must pass a class <i>instance</i>,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync not the class itself.</li>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync <li><a name="HiddenParams">Many XPCOM <b> method signatures</b> specify
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync "count" or "size" parameters. For example, every
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync time an array is passed via XPCOM, the method signature will always specify
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync an integer that holds the count of the array. These parameters are
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync always hidden in Python. As the size param can be implied from the
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync length of the Python sequence passed, the Python programmer need never pass
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync these parameters; in contrast, JavaScript requires these redundant parameters.</a></li>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<p>Most people can ignore this information - Python XPCOM objects just
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncwork. However, if you are familiar with xpcom from C++ and the concept of <i>QueryInterface</i>,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncyou may like to read this.</p>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<p>Most components support the concept of "interface
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncflattening". Such objects can report the interfaces they support,
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncallowing languages such as Python and Javascript avoid using <i>QueryInterface</i>.
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncWhen you are using an XPCOM object from Python, you can just call methods and
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncreference properties without regard for the interface that implements it.</p>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsync<p>When multiple interfaces share the same method or property name, you can use
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncthe name of the interface as a differentiator. Thus, <i>ob.nsIFoo.close()</i>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncwill call close on <i>ob</i>'s <i>nsIFoo</i> interface, while <i>ob.nsIBar.close()</i>
16a8d09569a2ebd598cef72fa605be6fb4563607vboxsyncwill use the <i>nsIBar</i> interface. <i>ob.close()</i> is not defined.</p>