El API de MorphOS y su Organización #aMiGaTrOnIcS

El API (Application Programmer Interface) de un sistema operativo consiste normalmente de miles de funciones. MorphOS no es una excepción. Sin embargo su núcleo (kernel) no es monolítico. El API está funcionalmente (y físicamente) dividido en librerías. Unas de las librerías más grandes pueden tener mas de 50 funciones. Un conjunto de las librerías más importantes están en la imagen del sistema de arranque. El resto están situadas en lo directorios de la  partición del sistema MOSSYS:Libs (librerías entregadas con el sistema) y SYS:Libs (librerías de terceras personas). Las librerías que están en disco se cargan bajo demanda. Todas estas librerías son compartidas, lo que significa que todos los procesos que usen una librería ejecutan el mismo código cargado en memoria una sola vez.

Repaso a las Librerías

MorphOS viene con mas de 100 librerías diferentes. No están todas mostradas a continuación, solo las más comunes. Navega en el SDK por los autodocs del sistema para ver más.

  • exec.library, la librería maestra. Es el núcleo del sistema, responsable de la planificación, control  y creación de procesos, comunicación entre procesos, gestión de memoria, gestión de otras librerías y control general del sistema. Esta es la única librería que siempre está abierta y no se puede cerrar.
  • dos.library, responsable de las entradas/salidas de ficheros y consola. Proporciona un interfaz de funciones de ficheros (como escanear directorios por ejemplo). Coopera con la exec.library en el proceso de creación. Proporciona servicios básicos de tiempo del sistema.
  • graphics.library, es responsable de funciones de bajo-nivel como dibujado de puntos y otras primitivas, copiar bloques rectangulares de la pantalla, desplazamiento etc. Muchos programas no la usan directamente.
  • intuition.library, proporciona objetos de la interfaz gráfica de nivel intermedio como pantallas y ventanas. Gestiona los dispositivos de entrada del usuario (ratón y teclado por nombrar algunos). Proporciona controles muy básicos de usuario (gadgets). También proporciona BOOPSI (Basic Object Oriented System for Intuition), un framework de programación orientado a objetos independiente del lenguaje, comúnmente utilizado por otros componentes.
  • muimaster.library, el acceso principal a MUI (Magic User Interface), que es un conjunto de herramientas GUI de alto nivel de MorphOS. Suministra un completo marco de trabajo (basado en BOOPSI) para aplicaciones GUI y un rico conjunto de objetos GUI.
  • locale.library, es responsable de la internacionalización del sistema y las aplicaciones. Este sencillo pero potente subsistema permite soportar múltiples versiones de lenguaje de un programa con un solo ejecutable, tambien proporciona datos de localización como el formato de fecha, la moneda local, la zona horaria, número de agrupación y más.
  • bsdsocket.library es una interfaz de red TCP/IP, compatible con conexiones BSD. Lo que es inusual con esta librería, es que no está ni en el kernel, ni en el disco duro. La pila TCP/IP la crea en memoria dinámicamente.

 

Cómo Usar una Librería en una Aplicación

En casos normales es casi automático. Lo único que hay que hacer es incluir el fichero de cabecera principal de la librería, que es <proto/[libname].h>, por ejemplo <proto/exec.h><proto/muimaster.h> y así. LA apertura y cierre de la librería se hace automáticamente por el código de inicio suministrado por libnixixemul.library. Después ya se pueden usar funciones de la librería.

Algunas librerías grandes tienen subdirectorios aparte en el árbol de includes del sistema. Algunos ejemplos de esas librerías son exec.library, dos.library graphics.library. Los ficheros de cabecera en estos directorios contienen definiciones de constantes, estructuras de datos, atributos etc. usados por la librería, dividido por funcionalidad. La inclusión de estos ficheros depende de qué funciones se usan en la aplicación, por ejemplo para usar las funciones de gestión de memoria de la exec.library hay que incluir <exec/memory.h>.

Otras librerías tienen un único fichero de cabecera en el directorio de librerías. Por ejemplo <libraries/locale.h> <libraries/mui.h>. Este fichero puede incluirse con el fichero proto o no.

Hay algunos casos, donde el manejo automático de librerías no funciona, o no puede ser usado.

  • Librerías de terceras personas. La mayoría no incluyen la característica de autoapertura.
  • Código de inicio personalizado (enlazado con -nostartfiles).
  • Abrir librerías en subprocesos.
  • Apertura de librería dinámica bajo demanda.
  • La base de la librería ha sido definida en el código de aplicación. La autoapertura de esta librería se desactiva automáticamente.library

En todos estos, la librería debe usarse manualmente.

 Abrir y Cerrar una Librería Manualmente

Aunque no tan conveniente como el método automático, abrir y cerrar una librería manualmente no es muy complicado. Hay que definir una variable base de la librería, después hay que usar dos funciones de exec.libraryOpenLibrary() CloseLibrary().

La base de la librería está definida en su fichero proto (la cabecera principal) como una variable global. Es un puntero a una estructura Library, el cual debería ser tratado como un puntero opaco. El resultado devuelto por OpenLibrary() debe ponerse en la base de la librería antes de llamar a cualquier función de la librería. Después, cuando la librería no se necesite, debería cerrarse con CloseLibrary() usando la base de la librería como argumento. La forma de usar la hipotética foobar.library es como sigue:

/* inside <proto/foobar.h> */

struct Library *FoobarBase;

 

/* inside application */

#include <proto/foobar.h>

if (FoobarBase = OpenLibrary((STRPTR)"foobar.library", 7))
{
/* use library functions here */

CloseLibrary(FoobarBase);
}

La llamada a OpenLibrary() tiene dos argumentos. El primero es el nombre de la librería que vamos a abrirlibs. Es solo el nombre, sin camino (path). MorphOS busca la librería en unas cuantmossys.as localizaciones en el siguiente orden:

  • MOSSYS:Libs/
  • LIBS:
  • directorio actual de la aplicación
  • PROGDIR:Libs/

El PROGDIR: del cuarto camino es una asignación automática que apunta al directorio que contiene el ejecutable de la aplicación.

El segundo parámetro de OpenLibrary() is la versión mínima requerida. Si pones cero abres cualquier versión, cualquier número positivo significa  "esta versión o mayor". No hay forma mas sencilla de pedir una versión particular de una librería. Hay que darse cuenta que este método solo funciona si las versiones más recientes de la librería es compatible con las anteriores. Por otro lado evita tener múltiples versiones de la misma librería en el sistema, que es un problema de los objetos compartidos en Linux.

El valor que devuelve OpenLibrary() debe de comprobarse que no es NULL. Incluso una librería del sistema de inicio puede fallar al intentar abrirse (por ejemplo por poca memoria, o tener una versión muy vieja). Mostrar un mensaje de error en caso de fallo es definitivamente una buena idea. Cada llamada a OpenLibrary() con éxito debe ir con su CloseLibrary(). De lo contrario se estarán desperdiciando recursos. También hace que sea imposible eliminar librerías no utilizadas de la memoria.

Hay dos casos especiales para la apertura y cierre de librerías: exec.librarydos.library. La primera siempre está abierta y no se puede cerrar, como hemos dicho anteriormente. La base de la librería para ella (llamada SysBase) está definida e inicializada en el código de inicio. Si se declara manualmente en el código fuente de la aplicación, debe de ser declarada como extern. La dos.library se abre y cierra como cualquier otra librería, pero como el código de inicio la necesita, la DOSBase ya está definida e inicializada ahí. Es por eso que la aplicación no necesita abrir la dos.library antes de usarla. Si se va a declarar en una aplicación, DOSBase  también debe ser extern.

Como un legado histórico de Amiga, algunas de las más importantes bases de librería (SysBase, DOSBase, IntuitionBase, GfxBase y alguna más) no están definidas como  struct Library* si no como punteros a estructuras de librerías específicas. Programar directamente estas estructuras era inevitable en las primeras versiones de AmigaOS. En MorphOS no se necesita ni es recomendado. Se puede evitar las definiciones anteriores (que fuerzan un innecesario typecasting en OpenLibrary() CloseLibrary()) usando #defining __NOLIBBASE__ antes de incluir los ficheros proto. De esta forma se inhabilita las definiciones de las bases de librería. Todas las bases pueden (y deben) ser definidas explícitamente en el código como punteros a estructura Library.

También por razones tradicionales, los nombres de algunas bases de librería no siguen el esquema {Libname}Base. Las más importantes son: SysBase  para exec.libraryDOSBase para la dos.library (mayúsculas),  GfxBase para graphics.library, MUIMasterBase para muimaster.library (mayúsculas), CyberGfxBase para cybergraphics.library. En cualquier caso el nombre de la base se puede comprobar mirando en el fichero de cabecera de la librería.

Usar en nombre de la base adecuado es muy importante, pues se usa de manera implícita en las llamadas de las funciones de la librería.

 

Licencia de Creative Commons

El API de MorphOS y su Organización by Grzegorz Kraszewski is licensed under a Creative Commons Reconocimiento-CompartirIgual 4.0 Internacional License.
Creado a partir de la obra en http://krashan.ppa.pl/mph/morphos-api-and-its-organization.



Editar

Josepzin

No hay comentarios:

Publicar un comentario