2010-01-09 12 views
6

Sé que COM proporciona reutilización a nivel binario en todos los idiomas y aplicaciones. He leído que todos los componentes creados para COM deben cumplir con un diseño de memoria estándar para que sean independientes del idioma.¿Por qué es COM (Modelo de Objetos Componentes) independiente del lenguaje?

No entiendo qué significa "diseño de memoria estándar".

¿Qué hace que COM sea independiente del lenguaje?

Respuesta

9

Primero, algunos antecedentes técnicos: los compiladores de C++ generalmente generan algo llamado "vtable" para cualquier clase con funciones virtuales. Esto es básicamente una tabla de indicadores de función. El vtable contiene un puntero de función para cada método virtual implementado por una clase.

En COM, las interfaces son básicamente las clases base abstractas que unos implementos de componentes, por ejemplo .:

class CSomeComponent : IUnknown, ISomeOtherInterface { ... }; 

la viable para CSomeComponent incluirán los punteros de función para todos los métodos definidos en estas dos interfaces.

struct __imaginary_vtable_for_CSomeComponent 
{ 
    // methods required by IUnknown 
    HRESULT (*QueryInterface)(const IID& iid, void** ppv); 
    ULONG (*AddRef)(); 
    ULONG (*Release)(); 
    // methods required by ISomeOtherInterface 
    void (*foo)(); 
    ... 
}; 

Cualquier objeto instanciado tiene una referencia al vtable de su tipo dinámico. Así es como el programa sabe cómo llamar al método apropiado en los casos en que se anula un método de base en una clase derivada:

class Base 
{ 
public: 
    virtual void foo() { ... } 
} 

class Derived : public Base 
{ 
public: 
    virtual void foo() { ... } // overrides Base::foo() 
    virtual void bar() { ... } 
} 

... 

Base* X = new Derived; 
X->foo(); 

La última línea debe llamar Derived::foo. Esto funciona porque el objeto X tiene una referencia al vtable para la clase Derived. Como se dijo, el vtable es como una lista de indicadores de función. Ahora, vtables tienen un diseño fijo: Si la clase Derived hereda de la clase Base, el puntero de función para el método foo estarán en la misma posición relativa en Derived 's vtable que en Base' vtable s:

struct __imaginary_vtable_for_Base 
{ 
    void (*foo)(); 
}; 

// __imaginary_vtable_for_Base::foo = Base::foo 

struct __imaginary_vtable_for_Derived 
{ 
    void (*foo)(); 
    void (*bar)(); 
}; 

// __imaginary_vtable_for_Derived::foo = Derived::foo 

ahora, si el compilador ve algo como X->foo(), sabe que para todas las clases derivadas de Base, el método foo corresponde a la primera entrada en el vtable. Por lo tanto, emite una llamada al primer puntero a función, que en el caso X es una llamada al Derived::foo.

Respuesta a su pregunta: Los compiladores solo pueden generar componentes COM si generan la misma disposición para los vtables que la especificación COM. Los vtables se pueden implementar de varias maneras diferentes, especialmente cuando se trata de herencia múltiple (que se requiere con los componentes COM). Es necesario seguir cierto formato vtable para que cuando llame al método f, llame al método f y no a ningún otro método g que se encuentre en la posición f en el vtable de la clase de componente. Supongo que los compiladores COM-compliant esencialmente tienen que producir los mismos diseños de vtable que Microsoft Visual C++, ya que la tecnología COM fue definida por Microsoft.

P.S.: Disculpe por ser tan técnico, espero que la información anterior sea de alguna utilidad para usted.

+0

Esta publicación de blog de MSDN (http://blogs.msdn.com/oldnewthing/archive/2004/02/05/68017.aspx) también podría ayudar. – stakx

+0

+1 para una explicación muy agradable. – Ashish

0

Diseño de memoria estándar significa un diseño de memoria que está definido (estandarizado) en la especificación COM, en lugar de lo que el predeterminado usa el lenguaje de llamada o definición. ¡Y es exactamente este tipo de cosas lo que lo hace independiente del lenguaje! El código en un lenguaje particular que llama a un objeto COM no tiene que importar en qué idioma se escribió ese objeto COM, en términos de conocer su estructura en la memoria.

0

Como recuerdo, COM es independiente del lenguaje y su estructura está documentada y abierta (?). La desventaja es que la estructura es "binaria" y está estrechamente ligada a C/C++, lo que dificulta el uso de otros lenguajes. La buena noticia es que muchos idiomas (como Python) tienen una interfaz C/C++, lo que hace posible (el módulo Win32com Python) utilizar desde otros idiomas.

JSON es independiente del lenguaje de una manera que no se correlaciona directamente a cualquier idioma, aunque Python, Perl y Ruby (?) Están cerca, pero es casi imposible utilizar de C/C++

Esperanza esta tiene algún tipo de sentido

+4

-1 porque la desventaja declarada es simplemente incorrecta y porque comparar COM y JSON es como comparar un motor con una bolsa. – Fredrik

+0

Bueno, sí y no, yo diría que puede ver COM como una interfaz de transporte para que un cliente acceda a un "servidor", como un servicio web. Si el servicio web está basado en REST, a menudo usará JSON. Por lo tanto, en mi opinión, la comparación no es tan descabellada ... – raindog

4

Don Box escribió una excelente explicación en el primer capítulo de su libro Essential COM. Puedes leerlo here gratis. Lo recomiendo.

Cuestiones relacionadas