Compartir a través de


¿Qué es una interfaz COM?

Si conoce C# o Java, las interfaces deben ser un concepto familiar. Una interfaz define un conjunto de métodos que un objeto puede admitir, sin dictar nada sobre la implementación. La interfaz marca un límite claro entre el código que llama a un método y el código que implementa el método . En términos de informática, el autor de la llamada se desacopla de la implementación.

Ilustración en la que se muestra el límite de la interfaz entre un objeto y una aplicación

En C++, el equivalente más cercano a una interfaz es una clase virtual pura, es decir, una clase que solo contiene métodos virtuales puros y ningún otro miembro. Este es un ejemplo hipotético de una interfaz:

// The following is not actual COM.

// Pseudo-C++:

interface IDrawable
{
    void Draw();
};

La idea de este ejemplo es que se puede dibujar un conjunto de objetos en alguna biblioteca de gráficos. La IDrawable interfaz define las operaciones que cualquier objeto dibujable debe admitir. (Por convención, los nombres de interfaz comienzan por "I"). En este ejemplo, la IDrawable interfaz define una sola operación: Draw.

Todas las interfaces son abstractas, por lo que un programa no pudo crear una instancia de un IDrawable objeto como tal. Por ejemplo, el código siguiente no se compilaría.

IDrawable draw;
draw.Draw();

En su lugar, la biblioteca de gráficos proporciona objetos que implementan la IDrawable interfaz . Por ejemplo, la biblioteca podría proporcionar un objeto shape para dibujar formas y un objeto de mapa de bits para dibujar imágenes. En C++, esto se hace heredando de una clase base abstracta común:

class Shape : public IDrawable
{
public:
    virtual void Draw();    // Override Draw and provide implementation.
};

class Bitmap : public IDrawable
{
public:
    virtual void Draw();    // Override Draw and provide implementation.
};

Las Shape clases y Bitmap definen dos tipos distintos de objeto dibujable. Cada clase hereda de IDrawable y proporciona su propia implementación del Draw método . Naturalmente, las dos implementaciones pueden diferir considerablemente. Por ejemplo, el Shape::Draw método podría rasterizar un conjunto de líneas, mientras que Bitmap::Draw podría dividir una matriz de píxeles.

Un programa que usa esta biblioteca de gráficos manipularía Shape objetos y Bitmap a través IDrawable de punteros, en lugar de utilizar Shape punteros o Bitmap directamente.

IDrawable *pDrawable = CreateTriangleShape();

if (pDrawable)
{
    pDrawable->Draw();
}

Este es un ejemplo que recorre en bucle una matriz de IDrawable punteros. La matriz puede contener una variedad heterogénea de formas, mapas de bits y otros objetos gráficos, siempre y cuando cada objeto de la matriz herede IDrawable.

void DrawSomeShapes(IDrawable **drawableArray, size_t count)
{
    for (size_t i = 0; i < count; i++)
    {
        drawableArray[i]->Draw();
    }
}

Un punto clave sobre COM es que el código que realiza la llamada nunca ve el tipo de la clase derivada. En otras palabras, nunca declararía una variable de tipo Shape o Bitmap en el código. Todas las operaciones de formas y mapas de bits se realizan mediante IDrawable punteros. De este modo, COM mantiene una separación estricta entre la interfaz y la implementación. Los detalles de implementación de las Shape clases y Bitmap pueden cambiar (por ejemplo, para corregir errores o agregar nuevas funcionalidades) sin cambios en el código de llamada.

En una implementación de C++, las interfaces se declaran mediante una clase o estructura.

Nota

Los ejemplos de código de este tema están diseñados para transmitir conceptos generales, no prácticas reales. La definición de nuevas interfaces COM está fuera del ámbito de esta serie, pero no definiría una interfaz directamente en un archivo de encabezado. En su lugar, se define una interfaz COM mediante un lenguaje denominado Interface Definition Language (IDL). Un compilador IDL procesa el archivo IDL, que genera un archivo de encabezado de C++.

class IDrawable
{
public:
    virtual void Draw() = 0;
};

Al trabajar con COM, es importante recordar que las interfaces no son objetos. Son colecciones de métodos que los objetos deben implementar. Varios objetos pueden implementar la misma interfaz, como se muestra con los Shape ejemplos y Bitmap . Además, un objeto puede implementar varias interfaces. Por ejemplo, la biblioteca de gráficos podría definir una interfaz denominada ISerializable que admita guardar y cargar objetos gráficos. Ahora tenga en cuenta las siguientes declaraciones de clase:

// An interface for serialization.
class ISerializable
{
public:
    virtual void Load(PCWSTR filename) = 0;    // Load from file.
    virtual void Save(PCWSTR filename) = 0;    // Save to file.
};

// Declarations of drawable object types.

class Shape : public IDrawable
{
    ...
};

class Bitmap : public IDrawable, public ISerializable
{
    ...
};

En este ejemplo, la Bitmap clase implementa ISerializable. El programa podría usar este método para guardar o cargar el mapa de bits. Sin embargo, la Shape clase no implementa ISerializable, por lo que no expone esa funcionalidad. En el diagrama siguiente se muestran las relaciones de herencia en este ejemplo.

ilustración que muestra la herencia de interfaz, con las clases de mapa de bits y forma que apuntan a idrawable, pero solo el mapa de bits que apunta a iserializable

En esta sección se ha examinado la base conceptual de las interfaces, pero hasta ahora no hemos visto código COM real. Comenzaremos con lo primero que debe hacer cualquier aplicación COM: Inicializar la biblioteca COM.

Siguientes

Inicialización de la biblioteca COM