Comparar revisiones

Un vistazo de XPCOM

Revisión 276227:

Revisión 276227 de Maharba el

Revisión 209667:

Revisión 209667 de Maharba el

Título:
Un vistazo de XPCOM
Un vistazo de XPCOM
Enlace amigable (slug):
Creación_de_Componentes_XPCOM/Un_vistazo_de_XPCOM
Creación_de_Componentes_XPCOM/Un_vistazo_de_XPCOM
Etiquetas:
XPCOM, Todas_las_Categorías
Contenido:

Revisión 276227
Revisión 209667
t7    <p>t
8      Este es un libro acerca de XPCOM. Esta escrito en forma de 
>un tutorial acerca de la creación de componentes XPCOM, pero cubr 
>e la mayoría de los aspectos, conceptos y terminología del modelo 
> de componentes XPCOM en el camino. 
9    </p>
10    <p>
11      Este capítulo empieza con un tour rápido de XPCOM - una int
>roducción a los conceptos básicos y tecnologías en XPCOM y el des 
>arrollo de componentes. Las secciones principales en este capítul 
>o introducen los conceptos a un nivel muy superficial, así que po 
>dremos discutirlos y usarlos con más familiaridad en el tutorial  
>que describe la creación del componente Mozilla llamado <strong>W 
>eblock</strong>. 
12    </p>
13    <h3 id="La_Soluci.C3.B3n_XPCOM" name="La_Soluci.C3.B3n_XPCOM"
>> 
14      La Solución XPCOM
15    </h3>
16    <p>
17      El Modelo Componente Objeto Multiplataforma (XPCOM) es una 
>plataforma que permite a los desarrolladores romper proyectos de  
>software monolíticos en piezas modulares más pequeñas. Estas piez 
>as, conocidas como <em>componentes</em> son ensamblados juntos nu 
>evamente en tiempo de ejecución. 
18    </p>
19    <p>
20      El objetivo de XPCOM es permitir a diferentes piezas de sof
>tware ser desarrolladas y construidas independientes unas de otra 
>s. Para permitir interoperabilidad entre componentes dentro de un 
>a aplicación, XPCOM separa la <em>implementación</em> de un compo 
>nente de la <em>interfaz</em>, lo cual discutimos en {{ Anch("Int 
>erfases") }}. Pero XPCOM también provee muchas herramientas y bib 
>liotecas que habilitan la carga y manipulación de estos component 
>es, servicios que ayudan al desarrollador a escribir código modul 
>ar multiplataforma, y soporte para versiones, así que los compone 
>ntes pueden ser reemplazados o actualizados sin tener que romper  
>o volver a crear la aplicación. Usando XPCOM, los desarrolladores 
> crean componentes que pueden ser reutilizados en diferentes apli 
>caciones o pueden ser reemplazados para cambiar la funcionalidad  
>de aplicaciones existentes. 
21    </p>
22    <p>
23      XPCOM no solamente soporta el desarrollo de componetes de s
>oftware, también provee gran parte de la funcionalidad de una pla 
>taforma de desarrollo, como: 
24    </p>
25    <ul>
26      <li>gestión de componentes
27      </li>
28      <li>abstracción de archivos
29      </li>
30      <li>paso de mensajes objeto
31      </li>
32      <li>manejo de memoria
33      </li>
34    </ul>
35    <p>
36      Discutiremos los puntos de arriba a detalle en los siguient
>es capítulos, pero por ahora, puede ser útil pensar en XPCOM como 
> una <em>plataforma para desarrollo de componentes</em>, en la qu 
>e la que se incluyen características como las listadas arriba. 
37    </p>
38    <h3 id="Gecko" name="Gecko">
39      Gecko
40    </h3>
41    <p>
42      Aunque en algunos aspectos es similar a Microsoft COM, XPCO
>M está diseñado para ser usado primordialmente a nivel de aplicac 
>ión. El uso más importante de XPCOM es dentro de <em>Gecko</em>,  
>un buscador web embebido de código abierto, que cumple con estánd 
>ares y un conjunto de herramientas para crear buscadores web y ot 
>ras aplicaciones. 
43    </p>
44    <p>
45      XPCOM se encarga de accesar la funcionalidad de las bibliot
>ecas de <em>Gecko</em> y embeber o extender Gecko. Este libro se  
>enfoca en lo último - extender Gecko - pero las ideas fundamental 
>es en el libro también serán importantes para los desarrolladores 
> que embeban Gecko. 
46    </p>
47    <p>
48      Gecko es usado en muchas aplicaciones de internet, la mayor
>ía buscadores. La lista incluye dispositivos como el Gateway/AOL, 
> el Instant AOL y la Nokia Media Terminal. Gecko también se usa e 
>n el último cliente Compuserve, AOL para Mac OS X, Netscape 7 y p 
>or supuesto el cliente de Mozilla. En este momento, Gecko es el w 
>eb browser de código abierto predominante. 
49    </p>
50    <h3 id="Componentes" name="Componentes">
51      Componentes
52    </h3>
53    <p>
54      XPCOM te permite construir un sistema en el que grandes pro
>yectos de software pueden ser fragmentados en piezas más pequeñas 
>. Estas piezas, conocidas como componentes, son normalmente diseñ 
>adas en pequeñas y reutilizables bibliotecas binarias(una <abbr t 
>itle="Dynamic Link Library">DLL</abbr> en Windows, por ejemplo, o 
> una <abbr title="Distributed Shared Object">DSO</abbr> en Unix), 
> que pueden incluir uno o más componentes. Cuando hay dos o más c 
>omponentes relacionados juntos en una biblioteca binaria, llamamo 
>s a la biblioteca <em>módulo</em>. 
55    </p>
56    <p>
57      Fragmentar el software en distintos componentes puede ayuda
>r a hacerlo menos difícil de desarrollar y mantener. Más allá de  
>esto, la programación modular basada en componentes tiene ciertas 
> ventajas bien conocidas: 
58    </p>
59    <table class="standard-table">
60      <tbody>
61        <tr>
62          <td class="header">
63            Beneficio
64          </td>
65          <td class="header">
66            Descripción
67          </td>
68        </tr>
69        <tr>
70          <td>
71            Reutlizable
72          </td>
73          <td>
74            El código modular puede ser reutilizado en otras apli
>caciones y en otros contextos. 
75          </td>
76        </tr>
77        <tr>
78          <td>
79            Actualizaciones
80          </td>
81          <td>
82            Puedes actualizar componentes sin tener que recompila
>r toda la aplicación. 
83          </td>
84        </tr>
85        <tr>
86          <td>
87            Rendimiento
88          </td>
89          <td>
90            Cuando el código es modular, los módulos que no serán
> usados en seguida pueden ser "cargados durmiendo", o no ser carg 
>ados del todo, lo que puede mejorar el rendimiento de tu aplicaci 
>ón. 
91          </td>
92        </tr>
93        <tr>
94          <td>
95            Mantenimiento
96          </td>
97          <td>
98            Aún cuando no estés actualizando un componente, diseñ
>ar tu aplicación de forma modular puede hacerte más fácil encontr 
>ar e mantener las partes de la aplicación en que estás interesado 
>. 
99          </td>
100        </tr>
101      </tbody>
102    </table>
103    <p>
104      Mozilla tiene más de cuatro millones de líneas de código, y
> ningún individuo por sí solo entiende el código fuente entero. L 
>a mejor forma de afrontar un proyecto de este tamaño es dividirlo 
> en piezas más pequeñas y manejables, usar un modelo de programac 
>ión basado en componentes y organizar ciertos grupos de component 
>es en módulos. La biblioteca de red, por ejemplo, consiste en com 
>ponentes para cada uno de los protocolos, HTTP, FTP y otros, los  
>cuales son armados juntos y enlazados en una sola biblioteca. Est 
>a biblioteca es el módulo de trabajo en red, conocida también com 
>o "necko". 
105    </p>
106    <p>
107      El componente <abbr title="Hypertext Transfer Protocol">HTT
>P</abbr> en Gecko no expone las clases privadas que usa como comp 
>onentes separados. El "stuff" 
108    </p>
109    <p>
110      The <abbr title="Hypertext Transfer Protocol">HTTP</abbr> c
>omponent in Gecko doesn't expose private classes it uses as separ 
>ate components. The "stuff" that's internal to the component stay 
>s internal, and isn't exposed to XPCOM. In the haste of early Moz 
>illa development, components were created where they were inappro 
>priate, but there's been an ongoing effort to remove XPCOM from p 
>laces like this. 
111    </p>
112    <p>
113      Pero no siempre es buena idea dividir las cosas. Hay alguna
>s cosas en el mundo que sólo trabajan si están juntas y otras que 
> deberían estar separadas. Por ejemplo, el hijo de un autor no se 
> comerá un sandwich de crema de cacahuate si no tiene jamón, porq 
>ue en este mundo, la crema de cachuate y el jamón forman una unió 
>n inseparable (guácala, en México como en muchos lugares no opina 
>mos lo mismo creo que fue un mal ejemplo, pero en fin esto es par 
>te de la traducción y espero se entienda la idea). Con el softwar 
>e es similar. En áreas de código que están estrechamente acoplada 
>s en clases que son usadas sólo internamente, por ejemplo, el dur 
>o trabajo de dividir las cosas tal vez no sea un esfuerzo vano. 
114    </p>
115    <p>
116      El componente <abbr title="Hypertext Transfer Protocol">HTT
>P</abbr> en Gecko no expone las clases privadas que usa como comp 
>onentes separados. El "material" que es interno del componente pe 
>rmanece interno y no es visible para XPCOM. Por la prisa al inici 
>o del desarrollo de Mozilla, fueron creados componentes donde era 
> inadecuado, pero se ha estado haciendo un grán esfuerzo para qui 
>tar XPCOM de estos lugares. 
117    </p>
118    <h3 id="Interfaces" name="Interfaces">
119      Interfaces
120    </h3>
121    <p>
122      Generalmente es buena idea dividir el software en component
>es, pero ¿Cómo hacer esto exactamente? La idea básica es identifi 
>car piezas de funcionalidad que esten relacionadas entre sí y ent 
>ender cómo se comunican entre ellas. Cuando son definidos los can 
>ales de comunicación entre los distintos delimitadores de forma q 
>ue se encuentran entre componentes y dichos delimitadores son for 
>malizados se llaman <em>interfaces</em>. 
123    </p>
124    <p>
125      Las interfaces no son una idea nueva en programación. Todos
> hemos usado interfaces desde nuestro primer programa "Hola Mundo 
>", donde la interface estaba entre el código que escribimos-el có 
>digo de la aplicación-y el código de impresión. El código de apli 
>cación usó una interfaz de una biblioteca, <code>stdio</code> par 
>a pintar la cadena "Hola Mundo" en la pantalla. La diferencia aqu 
>í es que una aplicación "Hola Mundo" en XPCOM encuentra esta pant 
>alla pintando funcionalidad en tiempo de ejecución y nunca tiene  
>que saber acerca de <code>stdio</code> cuando es compilado. 
126    </p>
127    <p>
128      Las interfaces permiten a los desarrolladores <em>encapsula
>r</em> la implementación y la lógica interna de su programa y per 
>mitir a los clientes ignorar cómo se hacen las cosas y sólo usar  
>el software. 
129    </p>
130    <div class="side-note">
131      <p>
132        {{ Block-title("Interfaces y programación por contrato") 
>}} 
133      </p>
134      <p>
135        Una interfaz forma un acuerdo contractual entre component
>es y clientes. No hay código que obligue estos acuerdos, pero ign 
>orarlos puede ser fatal. En la programación basada en componentes 
>, un componente garantiza que las interfaces que provee serán <em 
>>inmutables</em>, es decir, proveerán el mismo acceso a los mismo 
>s métodos en diferentes versiones del componente, estableciendo u 
>n contrato con los clientes que usan el software. A este respecto 
>, la programación basada en interfaces también es llamada <em>pro 
>gramación por contrato</em>. 
136      </p>
137    </div>
138    <h4 id="Interfaces_y_Encapsulaci.C3.B3n" name="Interfaces_y_E
>ncapsulaci.C3.B3n"> 
139      Interfaces y Encapsulación
140    </h4>
141    <p>
142      Entre delimitadores de componentes, la abstracción es cruci
>al para el mantenimiento y la reutilización del software. Conside 
>ra, por ejemplo, una clase que <em>no está</em> bien encapsulada; 
> usar un método público de inicialización disponible libremente,  
>como sugiere el ejemplo de abajo puede causar problemas. 
143    </p>
144    <p>
145      {{ Block-title("Inicializacion de AlgunaClase") }}
146    </p>
147    <pre>
148class AlgunaClase
149{
150  public:
151    // Constructor
152    AlgunaClase();
153 
154    // Virtual Destructor
155    virtual ~AlgunaClase();
156 
157    // init method
158    void Init();
159 
160    void HazAlgoUtil();
161};
162</pre>
163    <p>
164      Para que este sistema funcione correctamente, el programado
>r del cliente debe prestar mucha atención a todas las reglas que  
>el programador del componente estableció. Este es el acuerdo cont 
>ractual de esta clase clase no encapsulada: un conjunto de reglas 
> que definen cuando cada método puede ser llamado y cuando se esp 
>era que se haga. Una regla puede especificar que <code>HazAlgoUti 
>l</code> puede ser llamado sólo después de una llamada a <code>In 
>it()</code>. El método <code>HazAlgoUtil</code> puede hacer algún 
> tipo de validación para asegurar que la condición de que <code>I 
>nit()</code> ha sido llamado, ha sido cumplida. 
165    </p>
166    <p>
167      Además de escribir código bien comentado que le diga al des
>arrollador del cliente las reglas acerca de <code>Init()</code>,  
>el desarrollador puede seguir un par de pasos para hacer este con 
>trato más claro. Primero, la construcción de un objeto puede ser  
>encapsulada y proveer una <em>clase virtual</em> que defina el mé 
>todo <code>HazAlgoUtil</code>. De esta forma, construcción e inic 
>ialización pueden ser completamente ocultos de los clientes de la 
> clase. En esta situación "semiencapsulada", la única parte de la 
> clase que se ve esuna bien definida lista de métodos llamables ( 
>la interfaz). Una vez que la clase es encapsulada, la única inter 
>faz que verá el cliente es esta: 
168    </p>
169    <p>
170      {{ Block-title("Encapsulación de AlgunaInterfaz") }}
171    </p>
172    <pre>
173class AlgunaInterfaz
174{
175  public:
176    virtual void HazAlgoUtil() = 0;
177};
178</pre>
179    <p>
180      La implementación puede entonces derivar de esta clase e im
>plementar el método virtual. Los clientes de este código pueden u 
>sar después un patrón de diseño factoría para crear el objeto (ve 
> {{ Anch("Factorías") }}) y después encapsular la implementación. 
> En XPCOM, los clientes se escudan de la lógica interna de los co 
>mponentes de esta forma y confiar en la interfaz para proveer acc 
>eso a la funcionalidad requerida. 
181    </p>
182    <h4 id="La_Interfaz_Base_nsISupports" name="La_Interfaz_Base_
>nsISupports"> 
183      La Interfaz Base <code>nsISupports</code>
184    </h4>
185    <p>
186      Dos aspectos fundamentales en la programación basada en com
>ponentes e interfaces son: la <em>Vida del componente</em>, tambi 
>én llamada <em>posesión del objeto</em> y las <em>llamadas de int 
>erfaz</em>, o poder identificar que interfaces soporta un compone 
>nte al momento de ejecución. Esta sección introduce la interfaz b 
>ase, que es la madre de todas las interfaces en XPCOM, <code>nsIS 
>upports</code>, la cual proporciona soluciones a estos dos aspect 
>os para los desarrolladores de XPCOM. 
187    </p>
188    <h5 id="Posesi.C3.B3n_de_Objetos" name="Posesi.C3.B3n_de_Obje
>tos"> 
189      Posesión de Objetos
190    </h5>
191    <p>
192      Como los componentes en XPCOM pueden implementar cualquier 
>número de interfaces, dichas interfaces deben ser "contadas por r 
>eferencia". Los componentes deben tener control de cuántas refere 
>ncias a él tienen activas los clientes y borrarse ellos mismos cu 
>ando ese número llega a cero. 
193    </p>
194    <p>
195      Cuando un componente se crea, un entero dentro del componen
>te almacena esta <em>cuenta de referencias</em>. La cuenta de ref 
>erencias se incrementa automáticamente cuando el cliente hace una 
> instancia del componente; durante el transcurso de vida del comp 
>onente. En algún punto, todos los clientes pierden interés en el  
>componente, en ese momento la cuenta llega a cero y el componente 
> se borra a sí mismo. 
196    </p>
197    <p>
198      Cuando los clientes usan interfaces responsablemente, esto 
>puede ser un proceso muy serio. XPCOM tiene herramientas para hac 
>er esto más sencillo, como describiremos después. Podemos tener s 
>erios problemas cuando por ejemplo, un cliente usa una interfaz y 
> olvida decrementar la cuenta de referencia. Cuando esto pasa, la 
>s interfaces tal vez nunca puedan ser liberadas y se desbordará l 
>a memoria. El sistema de cuenta de referencias es, como muchas ot 
>ras cosas en XPCOM, un contrato entre clientes e implementaciones 
>. Trabaja cuando la gente se pone de acuerdo con él, pero si no,  
>las cosas pueden ir mal. Es responsabilidad de la funcion que cre 
>a el puntero a la interfaz añadir la referencia inicial o <em>pos 
>esión de referencia</em> a la cuenta. 
199    </p>
200    <div class="side-note">
201      <p>
202        {{ Block-title("Punteros en XPCOM") }}
203      </p>
204      <p>
205        En XPCOM, "punteros" se refiere a los punteros de interfa
>z. La diferencia es muy sutil ya que los punteros de interfaz y l 
>os punteros comunes son sólo direcciones en memoria. Pero un punt 
>ero de interfaz debe poder implementar la interfaz base nsISuppor 
>ts, que también puede ser usada para llamar métodos como <code>Ad 
>dRef</code>, <code>Release</code>, o <code>QueryInterface</code>. 
206      </p>
207    </div>
208    <p>
209      <code>nsISupports</code>, mostrado abajo, proporciona la fu
>ncionalidad básica para lidiar con el descubrimiento de la interf 
>az y la cuenta de referencias. Los miembros de esta interfaz, <co 
>de>QueryInterface</code>, <code>AddRef</code>, and <code>Release< 
>/code>, proporcionan los medios básicos para conseguir el interfa 
>z correcto de un objeto, incrementando la cuenta de referencias y 
> liberando objetos una vez que dejan de ser usados respectivament 
>e. La interfaz <code>nsISupports</code> se muestra a continuación 
>: 
210    </p>
211    <p>
212      {{ Block-title("La Interfaz <code>nsISupports</code>") }}
213    </p>
214    <pre>
215class Sample: public nsISupports
216{
217  private:
218    nsrefcnt mRefCnt;
219  public:
220    Sample();
221    virtual ~Sample();
222 
223    NS_IMETHOD QueryInterface(const nsIID &amp;aIID, void **aResu
>lt); 
224    NS_IMETHOD_(nsrefcnt) AddRef(void);
225    NS_IMETHOD_(nsrefcnt) Release(void);
226};
227</pre>
228    <p>
229      Los distintos tipos usados en la interfaz son descritos en 
>la sección {{ Anch("Tipos XPCOM") }} más adelante. Una implementa 
>ción completa de la interfaz <code>nsISupports</code> se muestra  
>abajo. Vea <a class="external" href="http://www.mozilla.org/proje 
>cts/xpcom/QI.html">A Reference Implementation of QueryInterface</ 
>a> para información más detallada. 
230    </p>
231    <p>
232      {{ Block-title("Implementación de la interfaz <code>nsISupp
>orts</code>") }} 
233    </p>
234    <pre>
235// inicializa la cuenta de referencias a 0
236Sample::Sample() : mRefCnt(0)
237
238}
239Sample::~Sample()
240{
241}
242 
243// típica implementación genérica de QI
244NS_IMETHODIMP Sample::QueryInterface(const nsIID &amp;aIID,
245                                  void **aResult)
246{
247  if (!aResult) {
248    return NS_ERROR_NULL_POINTER;
249  }
250  *aResult = NULL;
251  if (aIID.Equals(kISupportsIID)) {
252    *aResult = (void *) this;
253  }
254  if (!*aResult) {
255    return NS_ERROR_NO_INTERFACE;
256  }
257  // añade una referencia
258  AddRef();
259  return NS_OK;
260}
261 
262NS_IMETHODIMP_(nsrefcnt) Sample::AddRef()  
263{
264  return ++mRefCnt;
265}
266 
267NS_IMETHODIMP_(nsrefcnt) Sample::Release()
268{
269  if (--mRefCnt == 0) {
270    delete this;
271    return 0;
272  }
273  // opcional: regresa la cuenta de referencias
274  return mRefCnt;
275}
276</pre>
277    <h5 id="Descubrimiento_de_Objetos_de_Interfaz" name="Descubri
>miento_de_Objetos_de_Interfaz"> 
278      Descubrimiento de Objetos de Interfaz
279    </h5>
280    <p>
281      <em>Herencia</em> es otro tópico muy importante en la progr
>amación orientada a objetos. Herencia es el medio por el que una  
>clase es derivada de otra. Cuando una clase hereda de otra clase, 
> le clase hija puede <em>sobreescribir</em> los comportamientos o 
>riginales de la clase base sin tener que copiar todo el código de 
> esa clase, en efecto creando una clase más específica, como en e 
>l ejemplo siguiente: 
282    </p>
283    <p>
284      <br>
285      {{ Block-title("Herencia de la Clase Simple") }}
286    </p>
287    <pre>
288class Figura
289{
290  private:
291    int m_x;
292    int m_y;
293 
294  public:
295    virtual void Pintar() = 0;
296    Shape();
297    virtual ~Shape();
298};
299 
300class Circulo : public Figura
301{
302  private:
303    int m_radio;
304  public:
305    virtual Pintar();
306    Circulo(int x, int y, int radio);
307    virtual ~Circulo();
308};
309</pre>
310    <p>
311      <code>Circulo</code> es una clase derivada de <code>Figura<
>/code>. En otras palabras un <code>Circulo</code> es una <code>Fi 
>gura</code>, pero una <code>Figura</code> no es necesariamente un 
> <code>Circulo</code>. En este caso, <code>Figura</code> es la <e 
>m>clase base</em> y <code>Circulo</code> es una <em>subclase</em> 
> de <code>Figura</code>. 
312    </p>
313    <p>
314      En XPCOM, todas las clases derivan de la interfaz <code>nsI
>Supports</code>, así que todos los objetos son <code>nsISupports< 
>/code> pero también son otras clases más específicas que necesita 
>s para poder encontrarlas en tiempo de ejecución. En {{ Anch("Her 
>encia de la Clase Simple") }}, por ejemplo, ¿te gustaría poder pr 
>eguntarle a la <code>Figura</code> si es un <code>Circulo</code>  
>y poder usarlo como circulo si lo es? En XPCOM, esto es para lo q 
>ue está la caracteríztica <code>QueryInterface</code> de la inter 
>faz <code>nsISupports</code>: permite a los clientes encontrar y  
>accesar diferentes interfaces de acuerdo a sus necesidades. 
315    </p>
316    <p>
317      En C++, puedes usar un aspecto verdaderamente avanzado cono
>cido como <code>refernecia_dinámica&lt;&gt;</code>, que da una ex 
>cepción si el objeto <code>Figura</code> no puede hacer referenci 
>a a <code>Circulo</code>. Pero habilitar las excepciones y <abbr  
>title="Runtime Type Information">RTTI</abbr> puede no ser una opc 
>ión por la mejora del rendimiento y la compatibilidad en varias p 
>lataformas, así que XPCOM hace las cosas diferente. 
318    </p>
319    <div class="side-note">
320      <p>
321        {{ Block-title("Excepciones en XPCOM") }}
322      </p>
323      <p>
324        Las excepciones de C++ no son soportadas directamente en 
>XPCOM. Todas las excepciones deben ser gestionadas dentro de un c 
>omponente dado, antes de cruzar los límites de las interfaces. En 
> XPCOM, todos métodos de interfaz deben regresar un valor de erro 
>r <code>nsresult</code> (Vea la <a href="/es/Referencia_del_API_d 
>e_XPCOM" title="es/Referencia_del_API_de_XPCOM">Referencia del AP 
>I de XPCOM</a> para ver la lista de códigos de error). Esos resul 
>tados de códigos de error se vuelven "excepciones" que gestiona X 
>PCOM. 
325      </p>
326    </div>
327    <p>
328      En vez de utilizar el RTTI de C++, XPCOM usa el método espe
>cial <code>QueryInterface</code> que referencía el objeto a la in 
>terfaz correcta si esa interfaz es soportada. 
329    </p>
330    <p>
331      A cada interfaz se le asigna un identificador que se genera
> de una herramienta comunmente llamada "uuidgen". Este identifica 
>dor universal único es un número único de 128 bits. Usado en el c 
>ontexto de una interfaz (similar a un componente, donde el contra 
>ct ID(ID de contrato) hace esta función), a este número se le con 
>oce como <em>IID</em>. 
332    </p>
333    <p>
334      Cuando un cliente quiere saber si un objeto soporta una int
>erfaz dada, el cliente pasa el IID asignado a esa interfaz al mét 
>odo <code>QueryInterface</code> de ese objeto. Si el objeto sopor 
>ta la interfaz requerida, añade una referencia a sí mismo y regre 
>sa un puntero a esa interfaz. Si el objeto no soporta la interfaz 
>, regresa un error. 
335    </p>
336    <pre>
337class nsISupports { 
338  public:
339    long QueryInterface(const nsIID &amp; uuid,
340                        void **result) = 0;
341    long AddRef(void) = 0;
342    long Release(void) = 0;
343};
344</pre>
345    <p>
346      El primer parámetro de <code>QueryInterface</code> es una r
>eferencia a la clase llamada <code>nsIID</code>, que es una encap 
>sulación básica del IID. De los tres métodos en la clase <code>ns 
>IID</code>, <code>Equals</code>, <code>Parse</code>, and <code>To 
>String</code>, <code>Equals</code> es por mucho el más importante 
>, porque se usa para comparar dos <code>nsIID</code>s en el proce 
>so de requerimiento de esta interfaz. 
347    </p>
348    <p>
349      Cuando implementas la clase {{ Interface("nsISupports") }} 
>(y verás en el capítulo <a href="/es/Creaci%C3%B3n_de_Componentes 
>_XPCOM/Uso_de_Utilidades_XPCOM_para_hacer_las_cosas_m%C3%A1s_f%C3 
>%A1ciles" title="es/Creación_de_Componentes_XPCOM/Uso_de_Utilidad 
>es_XPCOM_para_hacer_las_cosas_más_fáciles">Uso de Utilidades XPCO 
>M para hacer las cosas más fáciles</a> como las macros pueden hac 
>er este proceso mucho más sencillo), debes asegurarte que los mét 
>odos de la clase regresan un resultado válido cuando el cliente l 
>lama <code>QueryInterface</code> con el IID de <code>nsISupports< 
>/code>. <code>QueryInterface</code> debe soportar todas las inter 
>faces que el componente soporta. 
350    </p>
351    <p>
352      En las implementaciones de <code>QueryInterface</code>, el 
>parámetro IID es comparado con el <code>nsIID</code> de la clase. 
> Si coinciden, el puntero <code>this</code> del objeto es referen 
>ciado a <code>void</code>, la cuenta de referencias se incrementa 
> y la interfaz es devuelta al llamador. Si no coinciden, la clase 
> regeresa un error y pone el valor de salida a <code>null</code>. 
353    </p>
354    <p>
355      En el ejemplo de arriba, es muy fácil usar referencias al e
>stilo de C. Pero referenciar puede volverse más complicado donde  
>debes primero referenciar a <code>void</code> y luego al tipo req 
>uerido porque debes regresar el puntero a la interfaz en el <abbr 
> title="virtual table">vtable</abbr> correspondiente a la interfa 
>z requerida. Referenciar puede volverse un problema cuando hay un 
> orden ambiguo de herencia. 
356    </p>
357    <h3 id="Identificadores_XPCOM" name="Identificadores_XPCOM">
358      Identificadores XPCOM
359    </h3>
360    <p>
361      Además del identificador de interfaz IID discutido en la se
>cción anterior, XPCOM usa otros dos identificadores muy important 
>es para distinguir las clases y los componentes. 
362    </p>
363    <div class="side-note">
364      <p>
365        {{ Block-title("Clases Identificadoras de XPCOM") }}
366      </p>
367      <p>
368        La clase <code>nsIID</code> es es un tupo definido para l
>a clase <code>nsID</code>. Los otros tipos definidos de <code>nsI 
>D</code>, CID e IID, se refieren a implementaciones específicas d 
>e una clase en concreto y a una iterfaz específica, respectivamen 
>te. 
369      </p>
370      <p>
371        La clase <code>nsID</code> proporciona métodos como <code
>>Equals</code> para comparar identificadores en el código. Ve <a  
>href="/es/Creaci%C3%B3n_de_Componentes_XPCOM/Creaci%C3%B3n_del_C% 
>C3%B3digo_del_Componente#Identificadores_en_XPCOM" title="es/Crea 
>ción_de_Componentes_XPCOM/Creación_del_Código_del_Componente#Iden 
>tificadores_en_XPCOM">Identificadores en XPCOM</a> para mayor inf 
>ormación de la clase <code>nsID</code>. 
372      </p>
373    </div>
374    <h4 id="CID" name="CID">
375      CID
376    </h4>
377    <p>
378      Un CID es un número de 128 bits que identifica como únicos 
>a una clase o un componente de manera muy parecida a la forma en  
>que un IID identifica una interfaz. El CID para <code>nsISupports 
></code> se ve como este: 
379    </p>
380    <p>
381      <code>00000000-0000-0000-c000-000000000046</code>
382    </p>
383    <p>
384      El largo de un CID puede hacer incómodo manejarlo en el cód
>igo, así que muy a menudo verás #defines para los CIDs y otros id 
>entificadores usados, como en el siguiente ejemplo: 
385    </p>
386    <pre>
387#define CID_EJEMPLO \ 
388{ 0x777f7150, 0x4a2b, 0x4301, \ 
389{ 0xad, 0x10, 0x5e, 0xab, 0x25, 0xb3, 0x22, 0xaa}} 
390</pre>
391    <p>
392      También verás que <code>NS_DEFINE_CID</code> es muy usado. 
>Esta simple macro declara una constante con el valor del CID: 
393    </p>
394    <pre>
395static NS_DEFINE_CID(kWebShellCID, NS_WEB_SHELL_CID);
396</pre>
397    <p>
398      Un CID es algunas veces llamado <em>identificador de clase<
>/em>. Si la clase a la que se refiere un CID implementa más de un 
>a interfaz, ese CID garantiza que la clase implementa todo ese co 
>njunto de interfaces cuando se publica como congelado. 
399    </p>
400    <h4 id="Contract_ID" name="Contract_ID">
401      Contract ID
402    </h4>
403    <p>
404      Un contract ID es una cadena leible humanamente usada para 
>accesar un componente. Un CID o un contract ID puede ser usado pa 
>ra obtener un componente desde el gestor de componentes. Este es  
>el contract ID para el componente de Operación LDAP: 
405    </p>
406    <pre>
407"@mozilla.org/network/ldap-operation;1"
408</pre>
409    <p>
410      El formato del contract ID es el <em>dominio</em> del compo
>nente, el <em>módulo</em>, el <em>nombre del componente</em> y el 
> <em>número de versión</em> separados por diagonales. 
411    </p>
412    <p>
413      Como un CID, el contract ID se refiere a una implementación
> más que a una interfaz, como lo hace un IID. Pero un contract ID 
> no está relacionado a ninguna implementación en específico, como 
> el CID, por lo cual es más general. Más bien, un contract ID esp 
>ecifica un conjunto de interfaces dadas que requiere implementada 
>s y cualquier número de CIDs diferentes pueden estar presentes y  
>llenar ese requerimiento. Esta diferencia entre un contract ID y  
>un CID es lo que hace posible sobreescribir componentes. 
414    </p>
415    <h3 id="Factor.C3.ADas" name="Factor.C3.ADas">
416      Factorías
417    </h3>
418    <p>
419      Una vez que el código es dividido en componentes, el código
> cliente típicamente usa el operador <code>new</code> para instan 
>ciar los objetos a usar: 
420    </p>
421    <pre>
422SomeClass* component = new SomeClass();
423</pre>
424    <p>
425      Este patrón requiere que el cliente sepa algo acerca del co
>mponente, al menos qué tan grande es. El <em>patrón de diseño fac 
>toría</em> puede usarse para encapsular la construcción de objeto 
>s. El objetivo principal de una factoría es crear un objeto sin m 
>ostrar a los clientes la implementación e inicialización de este  
>objeto. En el ejemplo <code>SomeClass</code> la construcción e in 
>icialización de <code>SomeClass</code> que implementa la clase ab 
>stracta <code>SomeInterface</code>, es contenida dentro de la fun 
>ción <code>New_SomeInterface</code> que sigue el patrón de diseño 
> factoría: 
426    </p>
427    <p>
428      {{ Block-title("Encapsulación del Constructor") }}
429    </p>
430    <pre>
431int New_SomeInterface(SomeInterface** ret)
432{
433  // crea el objeto
434  SomeClass* out = new SomeClass();
435  if (!out) return -1;
436 
437  // inicializa el objeto
438  if (out-&gt;Init() == FALSE)
439  {
440    delete out;
441    return -1;
442  }
443 
444  // referencia de la interfaz
445  *ret = static_cast&lt;SomeInterface*&gt;(out);
446  return 0; 
447
448</pre>
449    <p>
450      La factoría es la clase que gestiona la creación de instanc
>ias separadas de un componente para su uso. En XPCOM, las factorí 
>as son implementaciones de la interfaz <code>nsIFactory</code> y  
>usan un patrón de diseño factoría como el ejemplo de arriba para  
>abstraer y encapsular la construcción e inicialización del objeto 
>. 
451    </p>
452    <p>
453      El ejemplo en {{ Anch("Encapsulación del Constructor") }} e
>s una versión simple sin estado de las factorías, pero programarl 
>o en el mundo real usualmente no es tan simple y en general las f 
>actorías necesitan guardar un estado. La factoría necesita, por l 
>o menos preservar información de qué objetos ha creado. Cuando un 
>a factoría gestiona instancias de una clase contenida en un bibli 
>oteca dinámica compartida, por ejemplo, necesita saber cuando pue 
>de descargar la biblioteca. Cuando la factoría preserva un estado 
>, puedes preguntarle si hay referencias esperando y saber si la f 
>actoría creó objetos. 
454    </p>
455    <p>
456      Otro estado que puede guardar una factoría es si un objeto 
>es o no <em>singleton</em>. Por ejemplo, si una factoría crea un  
>objeto que se supone debe ser singleton, entonces las llamadas su 
>bsecuentes a la factoría por el objeto deben regresar el mismo ob 
>jeto. Aunque que hay herramientas y mejores formas de gestionar u 
>n singleton (lo que discutiremos cuando hablemos del <code>nsISer 
>viceManager</code>), un desarrollador tal vez quiera usar esta in 
>formación para asegurarse de que sólo puede existir un objeto sin 
>gleton sin importar lo que hagan los clientes. 
457    </p>
458    <p>
459      Los requerimientos de una clase factoría pueden gestionarse
> de una manera estrictamente funcional con el estado guardado en  
>variables globales, pero hay beneficios de usar clases para las f 
>actorías. Cuando usas una clase para implementar la funcionalidad 
> de una factoría, por ejemplo, derivas de la interfaz <code>nsISu 
>pports</code>, que te permite manejar el tiempo de vida de los ob 
>jetos de la factoría por sí mismos. Esto es importante cuando qui 
>eres agrupar conjuntos de factorías y determinar si pueden ser de 
>scargados. Otro beneficio de usar la interfaz <code>nsISupports</ 
>code> es que puedes soportar otras interfaces al momento en que s 
>ean introducidas. Como mostraremos al discutir <code>nsIClassInfo 
></code>, algunas factorías permiten pedir información acerca de l 
>a implementación que tienen debajo, como el lenguaje en el está e 
>scrito el objeto, las interfaces que soporta, etc. Este tipo de " 
>comprobación futura" es una ventaja clave que se obtiene al deriv 
>ar de <code>nsISupports</code>. 
460    </p>
461    <h4 id="XPIDL_y_Bibliotecas_de_Tipos" name="XPIDL_y_Bibliotec
>as_de_Tipos"> 
462      XPIDL y Bibliotecas de Tipos
463    </h4>
464    <p>
465      Una manera fácil y potente de definir una interfaz es - en 
>efecto, un requerimiento para definir interfaces en un ambiente m 
>ultiplataforma, independiente del lenguaje- es usar un <em>lengua 
>je de definición de interfaces</em> (IDL). XPCOM usa su propia va 
>riante del Lenguaje de Definición de Interfaces (IDL) de CORBA OM 
>G llamado XPIDL, que te permite especificar métodos, atributos y  
>contantes de una interfaz dada y también definir herencia de inte 
>rfaz. 
466    </p>
467    <p>
468      Hay algunas desventajas de definir tu interfaz usando XPIDL
>. No hay soporte para herencia múltiple de una sola cosa; si defi 
>nes una interfaz nueva, no puede derivar de más de una interfaz;  
>otra limitante de las intertfaces en XPIDL es que los nombres de  
>los métodos deben ser únicos, no puedes tener dos métodos con el  
>mismo nombre aunque tomen distintos parámetros, es decir no se pe 
>rmite la sobrecarga de funciones, y el trabajo que implica tener  
>múltiples nombres de funciones no es agradable: 
469    </p>
470    <pre>
471void AlgoConInt(in int x);
472void AlgoConString(in string x);
473void AlgoConURI(in nsIURI x);
474</pre>
475    <p>
476      De cualquier modo, estos pequeños inconvenientes palidecen 
>en comparación con la funcionalidad ganada usando XPIDL. XPIDL te 
> permite generar <em>bibliotecas de tipos</em>, o typelibs, que s 
>on archivos con la extensión <em>.xpt</em>. La biblioteca de tipo 
> es una representación binaria de una interfaz o interfaces, perm 
>ite el control programático y acceso de la interfaz, lo que es cr 
>ucial para las interfaces que no son usadas en el mundo de C++. C 
>uando los componentes son accesados desde otros lenguajes,como pu 
>ede hacerse en XPCOM, usan la biblioteca binaria de tipo para acc 
>esar a la interfaz, ver qué métodos soporta y llamar esos métodos 
>. Este aspecto de XPCOM se llama <em>XPConnect</em>. XPConnect es 
> la capa de XPCOm que permite el acceso a los componentes de XPCO 
>M desde lenguajes como JavaScript. Ve <a href="/es/Creaci%C3%B3n_ 
>de_Componentes_XPCOM/Uso_de_Componentes_XPCOM#Conexi.C3.B3n_a_Com 
>ponentes_desde_la_Interfaz" title="es/Creación_de_Componentes_XPC 
>OM/Uso_de_Componentes_XPCOM#Conexi.C3.B3n_a_Componentes_desde_la_ 
>Interfaz">Conexión a Componentes desde la Interfaz</a> para más i 
>nformación de XPConnect. 
477    </p>
478    <p>
479      Cuando un componente es accesible desde un lenguaje distint
>o a C++, como JavaScript, se le ordena a su interfaz "reflejarse" 
> en ese lenguaje. Cada interfaz reflejada debe tener una bibliote 
>ca de tipos correspondiente. Actualmente puedes escribir componen 
>tes en C, C++, Javascript (y algunas veces Python o Java, dependi 
>endo del estado de las etiquetas respectivas) y hay esfuerzos tra 
>tando de construir etiquetas XPCOm para Ruby y Perl también. 
480    </p>
481    <div class="side-note">
482      <p>
483        {{ Block-title("Escribir Componentes en Otros Lenguajes")
> }} 
484      </p>
485      <p>
486        Tal vez no tengas acceso a algunas de las herramientas qu
>e XPCOM da para los desarrolladores en C++ (como macros, plantill 
>as, punteros inteligentes y otros) cuando creas componentes en ot 
>ros lenguajes, tal vez te tengas que conformar con el lenguaje en 
> sí mismo prescindir de C++ y construir, por ejemplo, un componen 
>te XPCOm basado en Python que pueden ser usados desde JavaScript  
>o vice versa. 
487      </p>
488      <p>
489        Ve <a href="/es/Creaci%C3%B3n_de_Componentes_XPCOM/Resour
>ces" title="es/Creación_de_Componentes_XPCOM/Resources">Resources 
></a> Para más información de Python y otros lenguajes para los qu 
>e se ha añadido soporte en XPCOM. 
490      </p>
491    </div>
492    <p>
493      Todas las interfaces públicas en XPCOM sin definidas usando
> la sintaxis XPIDL. Las Bibliotecas de tipos y los archivos de ca 
>becera de C++ son generados a partir de estos archivos IDL y la h 
>erramienta que genera esos archivos se llama <em>compilador xpidl 
></em>. La sección <a href="/es/Creaci%C3%B3n_de_Componentes_XPCOM 
>/Iniciando_WebLock#Definici.C3.B3n_de_la_Interfaz_WebLock_en_XPID 
>L" title="es/Creación_de_Componentes_XPCOM/Iniciando_WebLock#Defi 
>nici.C3.B3n_de_la_Interfaz_WebLock_en_XPIDL">Definición de la Int 
>erfaz WebLock en XPIDL</a> describe la sintaxis XPIDL a detalle. 
494    </p>
495    <h3 id="Servicios_de_XPCOM" name="Servicios_de_XPCOM">
496      Servicios de XPCOM
497    </h3>
498    <p>
499      Cuando los clientes usan los componentes, normalmente <em>i
>nstancían</em> un nuevo objeto cada vez que necesitan la funciona 
>lidad que da un componente. Este es el caso cuando, por ejemplo,  
>los clientes lidian con archivos: cada archivo distinto es repres 
>entado por un objeto diferente y muchos objetos de archivo pueden 
> ser usados al mismo tiempo en cualquier momento. 
500    </p>
501    <p>
502      Pero también hay un tipo de objeto conocido como <em>servic
>io</em>, del cual siempre hay sólo una copia (aunque puede haber  
>varios servicios corriendo al mismo tiempo). Cada vez que un clie 
>nte quiere accesar la funcionalidad de un servicio, se comunican  
>con la misma instancia de ese servicio. Cuando un usuario busca u 
>n número telefónico en la base de datos de una compañía , por eje 
>mplo, probablemente esa base de datos está representada por un "o 
>bjeto" que es el mismo para todos los trabajadores. Si no lo fuer 
>a, la aplicación necesitaría varias copias de una gran base de da 
>tos en memoria, para una misma cosa y tal vez habría inconsistenc 
>ias entre los datos grabados porque las copias serían diferentes. 
503    </p>
504    <p>
505      Dar este único punto de acceso a la funcionalidad es para l
>o que está el patrón de diseño singleton y es lo que los servicio 
>s hacen en una aplicación (y en un ambiente de desarrollo como XP 
>COM). 
506    </p>
507    <p>
508      En XPCOM, además del soporte y gestión de componentes, hay 
>un número de servicios que ayudan al desarrollador a escribir com 
>ponentes multiplataforma. Estos servicios incluyen una abstracció 
>n de archivos multiplataforma que da un acceso a archivos uniform 
>e y potente, los servicios de directorio que mantienen la locació 
>n de la aplicación y locaciones específicas del sistema, manejo d 
>e memoria para asegurar que todos usen el mismo localizador de me 
>moria y el sistema de notificación de eventos que permite el paso 
> de mensajes simples. El tutorial mostrará cada uno de estos comp 
>onentes y servicios en uso, y la <a href="/es/XPCOM_API_Reference 
>" title="es/XPCOM_API_Reference">XPCOM API Reference</a> tiene un 
>a lista completa de las interfaces en éstas áreas. 
509    </p>
510    <h3 id="Tipos_de_XPCOM" name="Tipos_de_XPCOM">
511      Tipos de XPCOM
512    </h3>
513    <p>
514      Hay muchos tipos XPCOM declarados y macros simples que usar
>emos en los siguientes ejemplos, la mayoría de esos tipos son sim 
>ples correlaciones. Los tipos más comunes son descritos en las si 
>guientes secciones. 
515    </p>
516    <h4 id="Tipos_de_M.C3.A9todos" name="Tipos_de_M.C3.A9todos">
517      Tipos de Métodos
518    </h4>
519    <p>
520      Los siguientes son un conjunto de tipos para asegurar la co
>nvención correcta de llamadas y tipos regresados de los métodos X 
>PCOM. 
521    </p>
522    <table class="standard-table">
523      <tbody>
524        <tr>
525          <td>
526            <code>NS_IMETHOD</code>
527          </td>
528          <td>
529            Tipo regresado en la declaración del método. Las decl
>araciones de métodos XPCOM deben usar este como su tipo de regres 
>o. 
530          </td>
531        </tr>
532        <tr>
533          <td>
534            <code>NS_IMETHODIMP</code>
535          </td>
536          <td>
537            Tipo de regreso de implementación del método. Las imp
>lementaciones de métodos XPCOM deben usar este como su tipo de re 
>greso. 
538          </td>
539        </tr>
540        <tr>
541          <td>
542            <code>NS_IMETHODIMP_(tipo)</code>
543          </td>
544          <td>
545            Tipo de regreso de implementaciones de casos especial
>es. Algunos métodos como <code>AddRef</code> y <code>Release</cod 
>e> no regresan el tipo por defecto. Esta excepción es regrettable 
>, pero requerida para cumplir la compatibilidad con COM. 
546          </td>
547        </tr>
548        <tr>
549          <td>
550            <code>NS_IMPORT</code>
551          </td>
552          <td>
553            Forza el método a ser resuelto internamente por la bi
>blioteca compartida. 
554          </td>
555        </tr>
556        <tr>
557          <td>
558            <code>NS_EXPORT</code>
559          </td>
560          <td>
561            Forza el método a ser exportado por la biblioteca com
>partida. 
562          </td>
563        </tr>
564      </tbody>
565    </table>
566    <h4 id="Cuenta_de_Referencias" name="Cuenta_de_Referencias">
567      Cuenta de Referencias
568    </h4>
569    <p>
570      Estas Macros manejan la cuenta de referencias.
571    </p>
572    <table class="standard-table">
573      <tbody>
574        <tr>
575          <td>
576            <code>NS_ADDREF</code>
577          </td>
578          <td>
579            Llama a <code>AddRef</code> en un objeto <code>nsISup
>ports</code>. 
580          </td>
581        </tr>
582        <tr>
583          <td>
584            <code>NS_IF_ADDREF</code>
585          </td>
586          <td>
587            Lo mismo que el anterior pero valida null antes de ll
>amar a <code>AddRef</code>. 
588          </td>
589        </tr>
590        <tr>
591          <td>
592            <code>NS_RELEASE</code>
593          </td>
594          <td>
595            Llama a <code>Release</code> en un objeto <code>nsISu
>pports</code>. 
596          </td>
597        </tr>
598        <tr>
599          <td>
600            <code>NS_IF_RELEASE</code>
601          </td>
602          <td>
603            Lo mismo que el anterior pero valida null antes de ll
>amar a <code>Release</code>. 
604          </td>
605        </tr>
606      </tbody>
607    </table>
608    <h3 id="C.C3.B3digos_de_Estatus" name="C.C3.B3digos_de_Estatu
>s"> 
609      Códigos de Estatus
610    </h3>
611    <p>
612      Estas macros prueban códigos de estatus.
613    </p>
614    <table class="standard-table">
615      <tbody>
616        <tr>
617          <td>
618            <code>NS_FAILED</code>
619          </td>
620          <td>
621            Regresa verdadero si el código de estatus pasado fue 
>fallo. 
622          </td>
623        </tr>
624        <tr>
625          <td>
626            <code>NS_SUCCEEDED</code>
627          </td>
628          <td>
629            Regresa verdadero si el código de estatus pasado fue 
>éxito. 
630          </td>
631        </tr>
632      </tbody>
633    </table>
634    <h3 id="Correlaciones_Variables" name="Correlaciones_Variable
>s"> 
635      Correlaciones Variables
636    </h3>
637    <table class="standard-table">
638      <tbody>
639        <tr>
640          <td>
641            <code>nsrefcnt</code>
642          </td>
643          <td>
644            Tipo de cuenta de referencias por defecto. Correlacio
>na un entero de 32-bits. 
645          </td>
646        </tr>
647        <tr>
648          <td>
649            <code>nsresult</code>
650          </td>
651          <td>
652            Tipo de error por defecto. Correlaciona un entero de 
>32-bits. 
653          </td>
654        </tr>
655        <tr>
656          <td>
657            <code>nsnull</code>
658          </td>
659          <td>
660            Valor nulo por defecto.
661          </td>
662        </tr>
663      </tbody>
664    </table>
665    <h3 id="C.C3.B3digos_de_Error_Comunes_de_XPCOM" name="C.C3.B3
>digos_de_Error_Comunes_de_XPCOM"> 
666      Códigos de Error Comunes de XPCOM
667    </h3>
668    <table class="standard-table">
669      <tbody>
670        <tr>
671          <td>
672            <code>NS_ERROR_NOT_INITIALIZED</code>
673          </td>
674          <td>
675            Regresado cuando una instancia no está inicializada.
676          </td>
677        </tr>
678        <tr>
679          <td>
680            <code>NS_ERROR_ALREADY_INITIALIZED</code>
681          </td>
682          <td>
683            Regresado cuando una instancia ya fue inicializada.
684          </td>
685        </tr>
686        <tr>
687          <td>
688            <code>NS_ERROR_NOT_IMPLEMENTED</code>
689          </td>
690          <td>
691            Regresado por un método no implementado.
692          </td>
693        </tr>
694        <tr>
695          <td>
696            <code>NS_ERROR_NO_INTERFACE</code>
697          </td>
698          <td>
699            Regresado cuando una interfaz dada no es soportada.
700          </td>
701        </tr>
702        <tr>
703          <td>
704            <code>NS_ERROR_NULL_POINTER</code>
705          </td>
706          <td>
707            Regresado cuando un puntero válido es <code>nsnull</c
>ode>. 
708          </td>
709        </tr>
710        <tr>
711          <td>
712            <code>NS_ERROR_FAILURE</code>
713          </td>
714          <td>
715            Regresado cuando un método falla. Caso de error genér
>ico. 
716          </td>
717        </tr>
718        <tr>
719          <td>
720            <code>NS_ERROR_UNEXPECTED</code>
721          </td>
722          <td>
723            Regresado cuando ocurre un error inesperado.
724          </td>
725        </tr>
726        <tr>
727          <td>
728            <code>NS_ERROR_OUT_OF_MEMORY</code>
729          </td>
730          <td>
731            Regresado cuando una localización de memoria falla.
732          </td>
733        </tr>
734        <tr>
735          <td>
736            <code>NS_ERROR_FACTORY_NOT_REGISTERED</code>
737          </td>
738          <td>
739            Regresado cuando una clase requerida no está registra
>da. 
740          </td>
741        </tr>
742      </tbody>
743    </table>
744    <p>
745      {{ PreviousNext("Creación de Componentes XPCOM:Prefacio", "
>Creación de Componentes XPCOM:Uso de Componentes XPCOM") }} 
746    </p>
747    <p>
748      {{ languages( { "en": "en/Creating_XPCOM_Components/An_Over
>view_of_XPCOM", "zh-cn": "cn/\u521b\u5efa_XPCOM_\u7ec4\u4ef6/XPCO 
>M_\u7b80\u4ecb" } ) }} 
749    </p>

Volver al historial