Interior del Componente

  • Enlace amigable (slug) de la revisión: Creación_de_Componentes_XPCOM/Interior_del_Componente
  • Título de la revisión: Interior del Componente
  • Id de la revisión: 283014
  • Creada:
  • Creador: Maharba
  • ¿Es la revisión actual? No
  • Comentario /* Type Library Manifests */

Contenido de la revisión

{{template.PreviousNext("Creación de Componentes XPCOM:Using XPCOM Components", "Creación de Componentes XPCOM:Creating the Component Code")}} En el capítulo anterior describimos los componentes desde una perspectiva de un cliente de los componentes XPCOM, en este capútulo abordamos los componentes desde la perspectiva del desarrollador del programa. Léelo para ver como se implementan generalmente los componentes en XPCOM, o puedes brincarte al siguiente capítulo, donde el tutorial del componente WebLock te lleva paso a paso através del proceso de creación del componente. XXX mediawiki...XXX sucks

Creación de Componentes en C++

Empecemos por examinar como se escriben en C++ los componentes XPCOM. El tipo más común de componente es el escrito en C++ y compilado en una biblioteca compartida (una DLL en un sistema Windows o una DSO en Unix).

La imagen de abajo muestra la relación básica entre una biblioteca que contiene la implementación del código del componente que escribiste y la plataforma XPCOM en sí misma. En este diagrama, la superficie más externa del módulo es la biblioteca compartida en la que se define un componente.

{{wiki.template('Block-title', [ "Un Componente en la Plataforma XPCOM" ])}}

Image:component-internals-framework.png

Cuando construyes un componente o un módulo y lo compilas dentro de una biblioteca, debe exportar un método llamado NSGetModule. Esta función NSGetModule es el punto de acceso a la biblioteca. Es llamado durante el registro y el desregistro del componente y cuando XPCOM quiere descubrir qué interfaces o clases implementa el módulo/biblioteca. En este capítulo abordaremos todo este proceso.

Como ilustra {{template.Anch("Un Componente en la Plataforma XPCOM")}}, además del punto de acceso NSGetModule, están las interfaces nsIModule y nsIFactory que controlan la creación actual del componente y también las partes XPCOM glue y cadenas, que discutiremos un poco a detalle en la siguiente sección (Ve XPCOM Glue). Estas nos darán utilidades para desarrollo fácil más adelante como son punteros inteligentes, soporte de módulos genéricos e implementaciones simples de cadenas. La parte más larga y posiblemente la más compleja de un componente es el código específico del componente en sí mismo.

{{wiki.template('Block-title', [ "¿Pero Dónde Están los Componentes?" ])}}

Los componentes residen en módulos y esos módulos son definidos en bibliotecas compartidas típicamente situadas en el directorio components de una aplicación XPCOM.

Un conjunto de bibliotecas son almacenadas por defecto en este directorio components es lo que hay en una típica instalación de Gecko, dando la funcionalidad que consiste en trabajo en red, layout, composición, una interfaz de usuario multiplataforma y otros.

Otra vista aún más básica de esta relación de componentes a archivos e interfaces que los definen se muestra en Vista de Papel Cebolla de la creación del Componente XPCOM en el próximo capítulo. El componente es una abstracción situada entre el módulo actual en el que se implementa y los objetos que el código de su factoría crea para que uso de los clientes.

Inicialización de XPCOM

Para entender porqué y cuándo tu biblioteca de componentes es llamada, es importante entender el proceso de inicialización de XPCOM. Cuando inicia una aplicación, la aplicación puede inicializar XPCOM. La secuencia de eventos que lanza esta inicialización de XPCOM pueden ser lanzados por una ccioón del usuario o por el inicio de la aplicación en sí misma. Un buscador web que tiene embebido Gecko, por ejemplo, puede inicializar XPCOM al inicio atravéz de APIs embebidas. Otra aplicación puede este inicio hasta que XPCOM se necesite por primera vez. En otro caso, la secuencia de inicialización dentro de XPCOM es la misma.

XPCOM inicia cuando la aplicación hace una llamada para inicializarlo. Los parámetros pasados a esta llamada de inicialización te permiten configurar algunos aspectos de XPCOM, incluyendo la personalización de la ubicación de directorios específicos. El propósito principal del API en este punto es cambiar que directorio components inspecciona cuando busca componentes XPCOM. Así es como se usa el API, por ejemplo, en el Gecko Runtime Environment (GRE).

{{wiki.template('Block-title', [ "Inicialización de XPCOM" ])}}

Los seis pasos básicos para arrancar XPCOM son los siguientes:

  1. La aplicación inicia XPCOM.
  2. XPCOM envía una notificación que inicia el arranque.
  3. XPCOM encuentra y procesa el manifiesto del componente (ve {{template.Anch("Manifiestos de Componentes")}} abajo).
  4. Si hay nuevos componentes, XPCOM los registra:
    1. XPCOM llama el arranque del autoregistro.
    2. XPCOM registra los nuevos componentes.
    3. XPCOM llama el fin del autoregistro.
  5. Arranque completo de XPCOM: XPCOM notifica que ha iniciado.

Los manifiestos de Componentes y bibliotecas de tipos son descritos en la siguiente sección, {{template.Anch("Registro de Manifiestos de XPCOM")}}.

Registro de Manifiestos de XPCOM

XPCOM usa archivos especiales llamados manifiestos para cambiar y guardar información acerca de los componentes en el sistema local. Hay dos tipos de manifiestos que usa XPCOM para cambiar componentes:

Manifiestos de Componente

Cuando XPCOM inicia por primera vez, busca el manifiesto de componentes que es un archivo que lista todos los componentes registrados y guarda detalles de lo que exactamente puede hacer cada componente. XPCOM usa el manifiesto de componentes para determinar que componentes han sido sobreescritos. Empezando en Mozilla 1.2, este archivo es llamado compreg.dat y existe en el directorio components, pero hay esfuerzos por moverlo fuera de esta ubicación a una ubicación menos centrada en la aplicación y más centrada en el usuario. Cualquier aplicación bassada en Gecko puede escoger ponerlo en otro lado. XPCOM lee este archivo dentro de una base de datos en memoria.

{{wiki.template('Block-title', [ "Manifiestos de Componentes" ])}}

El manifiesto de componente es una correlación de archivos a componentes y de componentes a clases. Especifica la siguiente información:

  • Ubicación en disco de los componentes registrados con el tamaño de archivo
  • ID de Clase relacionado a la Ubicación.
  • Contract ID relacionado al ID de Clase.

El manifiesto del componente relaciona archivos de componentes a identificadores únicos para las implementaciones específicas (IDs de Clase), que en su momento son relacionados a identificadores de componente más generales (contract IDs).

Manifiestos de Bibliotecas de Tipos

Otro archivo importante que lee XPCOM es el manifiesto de bibliotecas de tipos. Este archivo tambien se localiza en el directorio components y se llama xpti.dat. Incluye la ubicación y direcciones de búsqueda de todas las bibliotecas de tipos en el sistema. este archivo también lista todas las interfaces conocidas y enlaces a los archivos de bibliotecas de tipos que definen estas estructuras de interfaces. Estos archivos de bibliotecas de tipos son el core para que XPCOM pueda ser script y de la arquitectura de componentes binarios de XPCOM.

{{wiki.template('Block-title', [ "Manifiestos de Bibliotecas de Tipos" ])}}

Type library manifests contain the following information:

  • location of all type library files
  • mapping of all known interfaces to type libraries where these structures are defined

Using the data in these two manifests, XPCOM knows exactly which component libraries have been installed and what implementations go with which interfaces. Additionally, it relates the components to the type libraries in which the binary representations of the interfaces they support are defined.

The next section describes how to hook into the XPCOM startup and registration process and make the data about your component available in these manifests, so that your component will be found and registered at startup.

Métodos de Registro en XPCOM

{{wiki.template('Block-title', [ "What Is XPCOM Registration?" ])}}

In a nutshell, registration is the process that makes XPCOM aware of your component(s). As this section and the next describe, you can register your component explicitly during installation, or with the regxpcom program, or you can use the autoregistration methods in the Service Manager to find and register components in a specified components directory:

  • XPInstall APIs
  • regxpcom command-line tool
  • nsIComponentRegistrar APIs from Service Manager

The registration process is fairly involved. This section introduces it in terms of XPCOM initialization, and the next chapter describes what you have to do in your component code to register your component with XPCOM.

Once the manifest files are read in, XPCOM checks to see if there are any components that need to be registered. There are two supported ways to go about registering your XPCOM component. The first is to use XPInstall, which is an installation technology that may or may not come with a Gecko application and provides interfaces for registering your component during installation. Another, more explicit way to register your component is to run the application regxpcom, which is built as part of Mozilla and is also available in the Gecko SDK. regxpcom registers your component in the default component registry.

A Gecko embedding application may also provide its own way of registering XPCOM components using the interface that is in fact used by both XPInstall and regxpcom, nsIComponentRegistrar. An application, for example, could provide a "registration-less" component directory whose components are automatically registered at startup and unregistered at shutdown. Component discovery does not currently happen automatically in non-debug builds of Gecko, however.

When the registration process begins, XPCOM broadcasts to all registered observers a notification that says XPCOM has begun the registration of new components. After all components are registered, another notification is fired saying that XPCOM is done with the registration step. The nsIObserver interface that handles this notification is discussed in Starting WebLock.

Once registration is complete and the notifications have fired, XPCOM is ready to be used by the application. If XPCOM registered your component, then it will be available to other parts of the XPCOM system. The {{template.Anch("XPCOM Initialization")}} section in this chapter describes registration in more detail.

Autoregistro

The term autoregistration is sometimes used synonymously with registration in XPCOM. In the {{template.Anch("What Is XPCOM Registration?")}} note, we describe the three ways you can register components with XPCOM. Sometimes, applications use the nsIComponentRegistrar interface and create their own code for watching a particular directory and registering new components that are added there, which is what's often referred to as autoregistration. You should always know what the installation and registration requirements are for the applications that will be using your component.

El Proceso de Paro

When the application is ready to shutdown XPCOM, it calls NS_ShutdownXPCOM. When that method is called, the following sequence of events occurs:

  1. XPCOM fires a shutdown notification to all registered observers.
  2. XPCOM closes down the Component Manager, the Service Manager and associated services.
  3. XPCOM frees all global services.
  4. NS_ShutdownXPCOM returns and the application may exit normally.

{{wiki.template('Block-title', [ "The Unstoppable Shutdown" ])}}

Note that shutdown observation is unstoppable. In other words, the event you observe cannot be used to implement something like a "Are you sure you want to Quit?" dialog. Rather, the shutdown event gives the component or embedding application a last chance to clean up any leftovers before they are released. In order to support something like an "Are you sure you want to quit" dialog, the application needs to provide a higher-level event (e.g., startShutdown()) which allows for cancellation.

Note also that XPCOM services may deny you access once you have received the shutdown notification. It is possible that XPCOM will return an error if you access the nsIServiceManager at that point, for example, so you may have to keep a reference-counted pointer to the service you are interested in using during this notification.

Component Loaders

Components can be written in many languages. So far this book has been focusing on "native components," shared libraries exporting a NSGetModule symbol. But if there is a component loader for Javascript installed, then you can also write a JavaScript component.

To register, unregister, load and manage various component types, XPCOM abstracts the interface between the XPCOM component and XPCOM with the Component Loader. This loader is responsible for initialization, loading, unloading, and supporting the nsIModule interface on behalf of each component. It is the Component Loader's responsibility to provide scriptable component support.

When building a "native" component, the component loader looks for an exported symbol from the components shared library. "Native" here includes any language that can generate a platform native dynamically loaded library. Scripting languages and other "non-native" languages usually have no way to build native libraries. In order to have "non-native" XPCOM components work, XPCOM must have a special component loader which knows how to deal with these type of components.

XPConnect, for example, provides a component loader that makes the various types, including the interfaces and their parameters, available to JavaScript. Each language supported by XPCOM must have a component loader.

Tres Partes de una Biblioteca de Componentes XPCOM

XPCOM is like an onionor a parfait! Everybody likes parfaits. XPCOM components have at least three layers. From the innermost and moving outward these layers include:

  • The core XPCOM object
  • The factory code
  • The module code

The core XPCOM object is the object that will implement the functionality you need. For example, this is the object that may start a network download and implement interfaces that will listen to the progress. Or the object may provide a new content type handler. Whatever it does, this object is at the core of the XPCOM component, and the other layers are supporting it, plugging it into the XPCOM system. A single library may have many of these core objects.

One layer above the core object is the factory code. The factory object provides a basic abstraction of the core XPCOM object. An Overview of XPCOM discussed the factory design pattern that's used in a factory object. At this layer of the XPCOM Component Library, the factory objects are factories for the core XPCOM objects of the layer below.

One more layer outward is the module code. The module interface provides yet another abstraction - this time of the factories - and allows for multiple factory objects. From the outside of the component library, there is only the single entry point, NSGetModule(). This point of entry may fan out to any number of factories, and from there, to any number of XPCOM objects.

The following chapter details these layers in terms of the XPCOM interfaces that represent them. Here we will just introduce them. The factory design pattern in XPCOM is represented by the nsIFactory interface. The module layer is represented by the nsIModule interface. Most component libraries only need these two interfaces, along with the nsISupports interface, to have XPCOM load, recognize, and use their core object code.

In the next section, we'll be writing the code that actually compiles into a component library, and you will see how each layer is implemented and how each interface is used. Following this initial, verbose demonstration of the APIs, we will introduce a faster more generic way of implementing the module and factory code using macros, which can make components much easier to create.

XPCOM Glue

XPCOM contains a lot of stuff. Most of the XPCOM interfaces are not frozen and are meant to be used only by the Gecko internals, not by clients. XPCOM provides many data structures from linked lists to AVL trees. Instead of writing your own linked list, it's tempting to reuse nsVoidArray or another publicly available class, but this might be a fatal mistake. At any time the class can change and give you unexpected behavior.

XPCOM makes for a very open environment. At runtime you can acquire any service or component merely by knowing a CID, or Contract ID, and an IID. At last count there were over 1300 interfaces defined in XPIDL. Of those 1300 interfaces, less than 100 were frozen, which means that a developer has a good chance of stumbling upon useful interfaces that aren't frozen. If an interface isn't explicitly marked "FROZEN" in the IDL comments, however - and most of them aren't - it will cause your component to possibly break or crash when the version changes.

La Biblioteca Glue

In general you should avoid any unfrozen interfaces, any symbols in XPCOM, or any other part of Gecko libraries that aren't frozen. However, there are some unfrozen tools in XPCOM that are used so often they are practically required parts of component programming.

The smart pointer class, nsCOMPtr, for example, which can make reference counting a lot less tedious and error-prone, is not actually frozen, and neither are nsDebug, a class for aiding in tracking down bugs, or nsMemory, a class to ensure that everyone uses the same heap, generic factory, and module. Instead of asking every developer to find and copy these various files into their own application, XPCOM provides a single library of "not-ready-to-freeze-but-really-helpful" classes that you can link into your application, as the following figure demonstrates.

{{wiki.template('Block-title', [ "XPCOM Glue and Tools" ])}}

Image:xpcom-glue-tools.png

This is the glue library. It provides a bridge, or "glue" layer, between your component and XPCOM.

A version of the glue library is built into XPCOM, and when your component uses it, it links a snapshot of this library: it includes a copy of these unfrozen classes directly, which allows the XPCOM library version to change without affecting the software. There is a slight footprint penalty to linking directly, but this gives your component freedom to work in any recent environment. If footprint is a big issue in your component or application, you can trim out the pieces you don't need.

XPCOM String Classes

The base string types that XPCOM uses are nsAString and nsACString. These classes are described in the Mozilla String Guide (see Gecko Resources).

The string classes that implement these abstract classes are another set of helpful, unfrozen classes in XPCOM. Most components and embedding applications need to link to some kind of string classes in order to utilize certain Gecko APIs, but the string code that Mozilla uses is highly complex and even more expensive than the glue code in terms of footprint (~100k). nsEmbedString and nsEmbedCString are available as very light string class implementations for component development, especially in small embedded applications. This string implementation does the bare minimum to support nsAString/nsACString string classes.

In your own component, you can go "slim" and restrict yourself to the nsEmbedString or go "hog wild" and use all of the functionality of the other strings. WebLock restricts itself to using the simple nsEmbedString family of classes.

{{wiki.template('Block-title', [ "String Classes and XPCOM" ])}}

Image:strings-in-xpcom.png

The glue library provides stub functions for the public functions that XPCOM provides (see {{template.Source("xpcom/build/nsXPCOM.h")}}). When the glue library is initialized, it dynamically loads these symbols from the XPCOM library, which allows the component to avoid linking directly with the XPCOM library. You shouldn't have to link to the XPCOM library to create a XPCOM component - in fact, if your component has to, then something is wrong. {{template.PreviousNext("Creating XPCOM Components:Using XPCOM Components", "Creating XPCOM Components:Creating the Component Code")}} {{template.CXCLicenseBlock()}}

Fuente de la revisión

<p>{{template.PreviousNext("Creación de Componentes XPCOM:Using XPCOM Components", "Creación de Componentes XPCOM:Creating the Component Code")}}
En el capítulo anterior describimos los componentes desde una perspectiva de un cliente de los componentes XPCOM, en este capútulo abordamos los componentes desde la perspectiva del desarrollador del 
programa. Léelo para ver como se implementan generalmente los componentes en XPCOM, o puedes brincarte al siguiente capítulo, donde el tutorial del componente WebLock te lleva paso a paso através del proceso de creación del componente.
<span class="comment">XXX mediawiki...</span><span class="comment">XXX             sucks</span>
</p>
<h3 name="Creaci.C3.B3n_de_Componentes_en_C.2B.2B"> Creación de Componentes en C++ </h3>
<p>Empecemos por examinar como se escriben en C++ los componentes XPCOM. El tipo más común de componente es el escrito en C++ y compilado en una biblioteca compartida (una <abbr title="Dynamic Link Library">DLL</abbr> en un sistema Windows o una <abbr title="Dynamic Shared Object">DSO</abbr> en Unix).
</p><p>La imagen de abajo muestra la relación básica entre una biblioteca que contiene la implementación del código del componente que escribiste y la plataforma XPCOM en sí misma. En este diagrama, la superficie más externa del módulo es la biblioteca compartida en la que se define un componente.
</p><p>{{wiki.template('Block-title', [ "Un Componente en la Plataforma XPCOM" ])}}
</p><p><img alt="Image:component-internals-framework.png" src="File:es/Media_Gallery/Component-internals-framework.png">
</p><p>Cuando construyes un componente o un módulo y lo compilas dentro de una biblioteca, debe exportar un método llamado <code>NSGetModule</code>. Esta función <code>NSGetModule</code> es el punto de acceso a la biblioteca. Es llamado durante el registro y el desregistro del componente y cuando XPCOM quiere descubrir qué interfaces o clases implementa el módulo/biblioteca. En este capítulo abordaremos todo este proceso.
</p><p>Como ilustra {{template.Anch("Un Componente en la Plataforma XPCOM")}}, además del punto de acceso <code>NSGetModule</code>, están las interfaces <code>nsIModule</code> y <code>nsIFactory</code> que controlan la creación actual del componente y también las partes XPCOM glue y cadenas, que discutiremos un poco a detalle en la siguiente sección (Ve <a href="es/Creaci%c3%b3n_de_Componentes_XPCOM/Interior_del_Componente#XPCOM_Glue">XPCOM Glue</a>). Estas nos darán utilidades para desarrollo fácil más adelante como son punteros inteligentes, soporte de módulos genéricos e implementaciones simples de cadenas. La parte más larga y posiblemente la más compleja de un componente es el código específico del componente en sí mismo.
</p>
<div class="side-note">
<p>{{wiki.template('Block-title', [ "¿Pero Dónde Están los Componentes?" ])}}
</p><p>Los componentes residen en módulos y esos módulos son definidos en bibliotecas compartidas típicamente situadas en el directorio <i>components</i> de una aplicación XPCOM.
</p><p>Un conjunto de bibliotecas son almacenadas por defecto en este directorio components es lo que hay en una típica instalación de 
Gecko, dando la funcionalidad que consiste en trabajo en red, layout, composición, una interfaz de usuario multiplataforma y otros.
</p><p>Otra vista aún más básica de esta relación de componentes a archivos e interfaces que los definen se muestra en <a href="es/Creaci%c3%b3n_de_Componentes_XPCOM/Creaci%c3%b3n_del_C%c3%b3digo_del_Componente">Vista de Papel Cebolla de la creación del Componente XPCOM</a> en el próximo capítulo. El componente es una abstracción situada entre el módulo actual en el que se implementa y los objetos que el código de su factoría crea para que uso de los clientes.
</p>
</div>
<h3 name="Inicializaci.C3.B3n_de_XPCOM"> Inicialización de XPCOM </h3>
<p>Para entender porqué y cuándo tu biblioteca de componentes es llamada, es importante entender el proceso de inicialización de XPCOM. Cuando inicia una aplicación, la aplicación puede <i>inicializar</i> XPCOM. La secuencia de eventos que lanza esta inicialización de XPCOM pueden ser lanzados por una ccioón del usuario o por el inicio de la aplicación en sí misma. Un buscador web que tiene embebido Gecko, por ejemplo, puede inicializar XPCOM al inicio atravéz de APIs embebidas. Otra aplicación puede este inicio hasta que XPCOM se necesite por primera vez. En otro caso, la secuencia de inicialización dentro de XPCOM es la misma.
</p><p>XPCOM inicia cuando la aplicación hace una llamada para inicializarlo. Los parámetros pasados a esta llamada de inicialización te permiten configurar algunos aspectos de XPCOM, incluyendo la personalización de la ubicación de directorios específicos. El propósito principal del API en este punto es cambiar que directorio <i>components</i> inspecciona cuando busca componentes XPCOM. Así es como se usa el API, por ejemplo, en el <i>Gecko Runtime Environment</i> (GRE).
</p>
<div class="side-note">
<p>{{wiki.template('Block-title', [ "Inicialización de XPCOM" ])}}
</p><p>Los seis pasos básicos para arrancar XPCOM son los siguientes:
</p>
<ol><li> La aplicación inicia XPCOM.
</li><li> XPCOM envía una notificación que inicia el arranque.
</li><li> XPCOM encuentra y procesa el <i>manifiesto del componente</i> (ve {{template.Anch("Manifiestos de Componentes")}} abajo).
</li><li> Si hay nuevos componentes, XPCOM los registra:
<ol><li> XPCOM llama el arranque del autoregistro.
</li><li> XPCOM registra los nuevos componentes.
</li><li> XPCOM llama el fin del autoregistro.
</li></ol>
</li><li> Arranque completo de XPCOM: XPCOM notifica que ha iniciado.
</li></ol>
<p>Los manifiestos de Componentes y bibliotecas de tipos son descritos en la siguiente sección, {{template.Anch("Registro de Manifiestos de XPCOM")}}.
</p>
</div>
<h4 name="Registro_de_Manifiestos_de_XPCOM"> Registro de Manifiestos de XPCOM </h4>
<p>XPCOM usa archivos especiales llamados manifiestos para cambiar y guardar información acerca de los componentes en el sistema local. Hay dos tipos de manifiestos que usa XPCOM para cambiar componentes:
</p>
<h5 name="Manifiestos_de_Componente"> Manifiestos de Componente</h5>
<p>Cuando XPCOM inicia por primera vez, busca el <i>manifiesto de componentes</i> que es un archivo que lista todos los componentes registrados y guarda detalles de lo que exactamente puede hacer cada 
componente. XPCOM usa el manifiesto de componentes para determinar que componentes han sido sobreescritos. Empezando en Mozilla 1.2, este archivo es llamado <code>compreg.dat</code> y existe en el directorio <i>components</i>, pero hay esfuerzos por moverlo fuera de esta ubicación a una ubicación menos centrada en la aplicación y más centrada en el usuario. Cualquier aplicación bassada en Gecko puede escoger ponerlo en otro lado. XPCOM lee este archivo dentro de una base de datos en memoria.
</p>
<div class="side-note">
<p>{{wiki.template('Block-title', [ "Manifiestos de Componentes" ])}}
</p><p>El manifiesto de componente es una correlación de archivos a componentes y de componentes a clases. Especifica la siguiente información:
</p>
<ul><li> Ubicación en disco de los componentes registrados con el tamaño de archivo
</li><li> ID de Clase relacionado a la Ubicación.
</li><li> Contract ID relacionado al ID de Clase.
</li></ul>
<p>El manifiesto del componente relaciona archivos de componentes a identificadores únicos para las implementaciones específicas (IDs de Clase), que en su momento son relacionados a identificadores de componente más generales (contract IDs).
</p>
</div>
<h5 name="Manifiestos_de_Bibliotecas_de_Tipos"> Manifiestos de Bibliotecas de Tipos </h5>
<p>Otro archivo importante que lee XPCOM es el <i>manifiesto de bibliotecas de tipos</i>. Este archivo tambien se localiza en el directorio <i>components</i> y se llama <code>xpti.dat</code>. Incluye la ubicación y direcciones de búsqueda de todas las bibliotecas de tipos en el sistema. este archivo también lista todas las interfaces conocidas y enlaces a los archivos de bibliotecas de tipos que definen estas estructuras de interfaces. Estos archivos de bibliotecas de tipos son el core para que XPCOM pueda ser script y de la arquitectura de componentes binarios de XPCOM.
</p>
<div class="side-note">
<p>{{wiki.template('Block-title', [ "Manifiestos de Bibliotecas de Tipos" ])}}
</p><p>Type library manifests contain the following information:
</p>
<ul><li> location of all type library files
</li><li> mapping of all known interfaces to type libraries where these structures are defined
</li></ul>
</div>
<p>Using the data in these two manifests, XPCOM knows exactly which component libraries have been installed and what implementations go with which interfaces. Additionally, it relates the components to the type libraries in which the binary representations of the interfaces they support are defined.
</p><p>The next section describes how to hook into the XPCOM startup and registration process and make the data about your component available in these manifests, so that your component will be found and registered at startup.
</p>
<h4 name="M.C3.A9todos_de_Registro_en_XPCOM"> Métodos de Registro en XPCOM </h4>
<div class="side-note">
<p>{{wiki.template('Block-title', [ "What Is XPCOM Registration?" ])}}
</p><p>In a nutshell, registration is the process that makes XPCOM aware of your component(s). As this section and the next describe, you can register your component explicitly during installation, or with the <code>regxpcom</code> program, or you can use the autoregistration methods in the Service Manager to find and register components in a specified components directory:
</p>
<ul><li> XPInstall APIs
</li><li> <code>regxpcom</code> command-line tool
</li><li> <code>nsIComponentRegistrar</code> APIs from Service Manager
</li></ul>
<p>The registration process is fairly involved. This section introduces it in terms of XPCOM initialization, and the next chapter describes what you have to do in your component code to register your component with XPCOM.
</p>
</div>
<p>Once the manifest files are read in, XPCOM checks to see if there are any components that need to be registered. There are two supported ways to go about registering your XPCOM component. The first is to use <i>XPInstall</i>, which is an installation technology that may or may not come with a Gecko application and provides interfaces for registering your component during installation. Another, more explicit way to register your component is to run the application <code>regxpcom</code>, which is built as part of Mozilla and is also available in the Gecko SDK. <code>regxpcom</code> registers your component in the default component registry.
</p><p>A Gecko embedding application may also provide its own way of registering XPCOM components using the interface that is in fact used by both XPInstall and <code>regxpcom</code>, <code>nsIComponentRegistrar</code>. An application, for example, could provide a "registration-less" component directory whose components are automatically registered at startup and unregistered at shutdown. Component discovery does not currently happen automatically in non-debug builds of Gecko, however.
</p><p>When the registration process begins, XPCOM broadcasts to all registered observers a notification that says XPCOM has begun the registration of new components. After all components are registered, another notification is fired saying that XPCOM is done with the registration step. The <code>nsIObserver</code> interface that handles this notification is discussed in <a href="es/Creating_XPCOM_Components/Starting_WebLock">Starting WebLock</a>.
</p><p>Once registration is complete and the notifications have fired, XPCOM is ready to be used by the application. If XPCOM registered your component, then it will be available to other parts of the XPCOM system. The {{template.Anch("XPCOM Initialization")}} section in this chapter describes registration in more detail.
</p>
<h4 name="Autoregistro"> Autoregistro </h4>
<p>The term <i>autoregistration</i> is sometimes used synonymously with registration in XPCOM. In the {{template.Anch("What Is XPCOM Registration?")}} note, we describe the three ways you can register components with XPCOM. Sometimes, applications use the <code>nsIComponentRegistrar</code> interface and create their own code for watching a particular directory and registering new components that are added there, which is what's often referred to as <i>autoregistration</i>. You should always know what the installation and registration requirements are for the applications that will be using your component.
</p>
<h4 name="El_Proceso_de_Paro"> El Proceso de Paro </h4>
<p>When the application is ready to shutdown XPCOM, it calls <code>NS_ShutdownXPCOM</code>. When that method is called, the following sequence of events occurs:
</p>
<ol><li> XPCOM fires a shutdown notification to all registered observers.
</li><li> XPCOM closes down the Component Manager, the Service Manager and associated services.
</li><li> XPCOM frees all global services.
</li><li> NS_ShutdownXPCOM returns and the application may exit normally.
</li></ol>
<div class="side-note">
<p>{{wiki.template('Block-title', [ "The Unstoppable Shutdown" ])}}
</p><p>Note that shutdown observation is unstoppable. In other words, the event you observe cannot be used to implement something like a "Are you sure you want to Quit?" dialog. Rather, the shutdown event gives the component or embedding application a last chance to clean up any leftovers before they are released. In order to support something like an "Are you sure you want to quit" dialog, the application needs to provide a higher-level event (e.g., <code>startShutdown()</code>) which allows for cancellation.
</p><p>Note also that XPCOM services may deny you access once you have received the shutdown notification. It is possible that XPCOM will return an error if you access the <code>nsIServiceManager</code> at that point, for example, so you may have to keep a reference-counted pointer to the service you are interested in using during this notification.
</p>
</div>
<h4 name="Component_Loaders"> Component Loaders </h4>
<p>Components can be written in many languages. So far this book has been focusing on "native components," shared libraries exporting a <code>NSGetModule</code> symbol. But if there is a <i>component loader</i> for Javascript installed, then you can also write a JavaScript component.
</p><p>To register, unregister, load and manage various component types, XPCOM abstracts the interface between the XPCOM component and XPCOM with the Component Loader. This loader is responsible for initialization, loading, unloading, and supporting the <code>nsIModule</code> interface on behalf of each component. It is the Component Loader's responsibility to provide scriptable component support.
</p><p>When building a "native" component, the component loader looks for an exported symbol from the components shared library. "Native" here includes any language that can generate a platform native dynamically loaded library. Scripting languages and other "non-native" languages usually have no way to build native libraries. In order to have "non-native" XPCOM components work, XPCOM must have a special component loader which knows how to deal with these type of components.
</p><p>XPConnect, for example, provides a component loader that makes the various types, including the interfaces and their parameters, available to JavaScript. Each language supported by XPCOM must have a component loader.
</p>
<h4 name="Tres_Partes_de_una_Biblioteca_de_Componentes_XPCOM"> Tres Partes de una Biblioteca de Componentes XPCOM </h4>
<p>XPCOM is like an onion<span class="comment">or a parfait!  Everybody likes parfaits</span>. XPCOM components have at least three layers. From the innermost and moving outward these layers include:
</p>
<ul><li> The core XPCOM object
</li><li> The factory code
</li><li> The module code
</li></ul>
<p>The core XPCOM object is the object that will implement the functionality you need. For example, this is the object that may start a network download and implement interfaces that will listen to the progress. Or the object may provide a new content type handler. Whatever it does, this object is at the core of the XPCOM component, and the other layers are supporting it, plugging it into the XPCOM system. A single library may have many of these core objects.
</p><p>One layer above the core object is the factory code. The factory object provides a basic abstraction of the core XPCOM object. <a href="es/Creating_XPCOM_Components/An_Overview_of_XPCOM">An Overview of XPCOM</a> discussed the factory design pattern that's used in a factory object. At this layer of the XPCOM Component Library, the factory objects are factories for the core XPCOM objects of the layer below.
</p><p>One more layer outward is the module code. The module interface provides yet another abstraction - this time of the factories - and allows for multiple factory objects. From the outside of the component library, there is only the single entry point, <code>NSGetModule()</code>. This point of entry may fan out to any number of factories, and from there, to any number of XPCOM objects.
</p><p>The following chapter details these layers in terms of the XPCOM interfaces that represent them. Here we will just introduce them. The factory design pattern in XPCOM is represented by the <code>nsIFactory</code> interface. The module layer is represented by the <code>nsIModule</code> interface. Most component libraries only need these two interfaces, along with the <code>nsISupports</code> interface, to have XPCOM load, recognize, and use their core object code.
</p><p>In the next section, we'll be writing the code that actually compiles into a component library, and you will see how each layer is implemented and how each interface is used. Following this initial, verbose demonstration of the APIs, we will introduce a faster more generic way of implementing the module and factory code using macros, which can make components much easier to create.
</p>
<h3 name="XPCOM_Glue"> XPCOM Glue </h3>
<p>XPCOM contains a lot of stuff. Most of the XPCOM interfaces are not frozen and are meant to be used only by the Gecko internals, not by clients. XPCOM provides many data structures from linked lists to <a class="external" href="http://en.wikipedia.org/wiki/AVL_tree">AVL trees</a>. Instead of writing your own linked list, it's tempting to reuse <code>nsVoidArray</code> or another publicly available class, but this might be a fatal mistake. At any time the class can change and give you unexpected behavior.
</p><p>XPCOM makes for a very open environment. At runtime you can acquire any service or component merely by knowing a CID, or Contract ID, and an IID. At last count there were over 1300 interfaces defined in XPIDL. Of those 1300 interfaces, less than 100 were frozen, which means that a developer has a good chance of stumbling upon useful interfaces that aren't frozen. If an interface isn't explicitly marked "FROZEN" in the IDL comments, however - and most of them aren't - it will cause your component to possibly break or crash when the version changes.
</p>
<h4 name="La_Biblioteca_Glue"> La Biblioteca Glue </h4>
<p>In general you should avoid any unfrozen interfaces, any symbols in XPCOM, or any other part of Gecko libraries that aren't frozen. However, there are some unfrozen tools in XPCOM that are used so often they are practically required parts of component programming.
</p><p>The smart pointer class, <code>nsCOMPtr</code>, for example, which can make reference counting a lot less tedious and error-prone, is not actually frozen, and neither are <code>nsDebug</code>, a class for aiding in tracking down bugs, or <code>nsMemory</code>, a class to ensure that everyone uses the same heap, generic factory, and module. Instead of asking every developer to find and copy these various files into their own application, XPCOM provides a single library of "not-ready-to-freeze-but-really-helpful" classes that you can link into your application, as the following figure demonstrates.
</p><p>{{wiki.template('Block-title', [ "XPCOM Glue and Tools" ])}}
</p><p><img alt="Image:xpcom-glue-tools.png" src="File:es/Media_Gallery/Xpcom-glue-tools.png">
</p><p>This is the glue library. It provides a bridge, or "glue" layer, between your component and XPCOM.
</p><p>A version of the glue library is built into XPCOM, and when your component uses it, it links a snapshot of this library: it includes a copy of these unfrozen classes directly, which allows the XPCOM library version to change without affecting the software. There is a slight footprint penalty to linking directly, but this gives your component freedom to work in any recent environment. If footprint is a big issue in your component or application, you can trim out the pieces you don't need.
</p>
<h4 name="XPCOM_String_Classes"> XPCOM String Classes </h4>
<p>The base string types that XPCOM uses are <code>nsAString</code> and <code>nsACString</code>. These classes are described in the Mozilla String Guide (see <a href="es/Creating_XPCOM_Components/Resources#Gecko_Resources">Gecko Resources</a>).
</p><p>The string classes that implement these abstract classes are another set of helpful, unfrozen classes in XPCOM. Most components and embedding applications need to link to some kind of string classes in order to utilize certain Gecko APIs, but the string code that Mozilla uses is highly complex and even more expensive than the glue code in terms of footprint (~100k). <code>nsEmbedString</code> and <code>nsEmbedCString</code> are available as very light string class implementations for component development, especially in small embedded applications. This string implementation does the bare minimum to support <code>nsAString</code>/<code>nsACString</code> string classes.
</p><p>In your own component, you can go "slim" and restrict yourself to the <code>nsEmbedString</code> or go "hog wild" and use all of the functionality of the other strings. WebLock restricts itself to using the simple <code>nsEmbedString</code> family of classes.
</p><p>{{wiki.template('Block-title', [ "String Classes and XPCOM" ])}}
</p><p><img alt="Image:strings-in-xpcom.png" src="File:es/Media_Gallery/Strings-in-xpcom.png">
</p><p>The glue library provides stub functions for the public functions that XPCOM provides (see {{template.Source("xpcom/build/nsXPCOM.h")}}). When the glue library is initialized, it dynamically loads these symbols from the XPCOM library, which allows the component to avoid linking directly with the XPCOM library. You shouldn't have to link to the XPCOM library to create a XPCOM component - in fact, if your component has to, then something is wrong.
{{template.PreviousNext("Creating XPCOM Components:Using XPCOM Components", "Creating XPCOM Components:Creating the Component Code")}}
{{template.CXCLicenseBlock()}}
</p>
Revertir a esta revisión