¡Puntuación alta (200 puntos)! Componente VCCOM
Los objetos COM se basan en el nivel de código ejecutable binario, mientras que los objetos en lenguajes como C se basan en el nivel de código fuente, por lo que los objetos COM son independientes del lenguaje. Esta característica permite interactuar con objetos componentes desarrollados en diferentes lenguajes de programación.
En la plataforma del sistema Microsoft Windows, la tecnología COM se aplica a todos los niveles del sistema, desde la gestión de objetos COM subyacentes hasta la interacción de aplicaciones de nivel superior.
Resumen
COM no solo propone especificaciones para la interacción entre componentes, sino que también proporciona un entorno interactivo. Debido a que la especificación de la interacción entre los objetos componentes no depende de ningún lenguaje específico, COM también puede convertirse en un estándar para el desarrollo colaborativo de diferentes lenguajes.
La tecnología OLE se basa en el estándar COM. OLE aprovecha al máximo el estándar COM y hace que las aplicaciones del sistema operativo Windows sean altamente interactivas. Sin soporte OLE, el sistema operativo Windows sería muy inferior.
Sin embargo, la especificación COM no se limita a la tecnología OLE. De hecho, la tecnología OLE es sólo una aplicación de COM. En los últimos años, la tecnología OLE ha mostrado grandes limitaciones en la interconexión de redes, mientras que COM ha mostrado una gran adaptabilidad.
Los estándares COM incluyen especificación e implementación. La parte de especificación define el mecanismo de comunicación entre componentes. Estas especificaciones son independientes de cualquier idioma y sistema operativo en particular, siempre que se pueda utilizar cualquier idioma de acuerdo con las especificaciones. La parte de implementación del estándar COM es la biblioteca COM, que proporciona algunos servicios centrales para la implementación específica de la especificación COM.
COM es un modelo de software orientado a objetos, por lo que los objetos son uno de sus elementos básicos. De manera similar al concepto de objetos en C, un objeto es una instancia de una clase. Una clase es una definición de un conjunto de datos y grupos funcionales relacionados. La aplicación que utiliza el objeto (u otro objeto) se convierte en el cliente y, a veces, en el usuario del objeto.
Una interfaz es un conjunto de funciones relacionadas lógicamente, y sus funciones también se denominan funciones miembro de la interfaz. Los objetos proporcionan diversas formas de servicios a los clientes a través de funciones miembro de la interfaz.
En el modelo COM, el objeto en sí es invisible para el cliente. Cuando el cliente solicita un servicio, solo se puede realizar a través de la interfaz. Cada interfaz se identifica mediante un identificador único global (GUID) de 128 bits. El cliente obtiene el puntero de la interfaz a través del GUID y puede llamar a su función miembro correspondiente a través del puntero de la interfaz.
En términos generales, la interfaz no cambia. Mientras la interfaz esperada por el cliente todavía exista en el objeto construido, puede continuar utilizando los servicios proporcionados por esa interfaz. Los objetos pueden admitir múltiples interfaces, por lo que la actualización de los objetos componentes se puede lograr agregando interfaces, de modo que la nueva interfaz no afecte el uso de la interfaz anterior.
¿Cómo identifican los clientes los objetos COM? De manera similar a las interfaces, cada objeto se identifica mediante un GUID de 128 bits llamado CLSID (identificador de clase o ID de clase). El uso de un CLSID para identificar un objeto garantiza (en un sentido probabilístico) la unicidad global.
Siempre que el sistema contenga información sobre este tipo de objeto COM, incluido el archivo del módulo (archivo DLL o EXE) donde se encuentra el objeto COM y el punto de entrada del objeto COM en el código, el El programa cliente puede crear un objeto COM a partir de este CLSID.
Entonces, ¿cómo utilizan los clientes los servicios proporcionados por los objetos COM? ¿Qué obtiene el cliente?
De hecho, después de que el cliente crea exitosamente el objeto, obtendrá un puntero a la interfaz del objeto. Debido a que un objeto COM implementa al menos una interfaz, los clientes pueden llamar a todos los servicios proporcionados por esa interfaz.
Pero los objetos COM pueden tener su propio estado, lo que permite a los clientes sentir la existencia de objetos COM.
Si el cliente posee dos objetos con el mismo CLSID al mismo tiempo, entonces los dos objetos pueden tener estados diferentes. El cliente no necesita preocuparse por cómo se implementa el objeto COM y cuál es la relación entre los datos de estado (matriz o. lista enlazada) de los dos objetos. Por supuesto, los objetos COM también pueden ser sin estado, proporcionando principalmente servicios funcionales y pueden usarse para reemplazar las interfaces de funciones API tradicionales para hacer que las interfaces de programación de aplicaciones sean más ordenadas y jerárquicas.
Además de las especificaciones, COM también tiene algunas partes de implementación, incluidos algunos códigos centrales a nivel de sistema que permiten que objetos y clientes interactúen a nivel de código binario a través de interfaces.
En el entorno del sistema operativo Microsoft Windows, estas bibliotecas comienzan con . dll, que incluye el siguiente contenido:
(1) Proporciona una pequeña cantidad de funciones API para realizar el proceso de creación de aplicaciones COM del lado del cliente y del servidor. En el lado del cliente, se trata principalmente de algunas funciones de creación; en el lado del servidor, proporciona soporte de acceso para algunos objetos.
(2) COM busca en el servidor local, es decir, el programa EXE, y convierte el nombre del programa y CLSID a través del registro.
(3) Proporciona algunos métodos de control de memoria estándar para permitir que las aplicaciones controlen la asignación de memoria en el proceso.
Las bibliotecas COM generalmente no se implementan a nivel de aplicación, sino a nivel de sistema operativo, por lo que solo existe una biblioteca COM para un sistema operativo. Además, la implementación de la biblioteca COM debe depender de la plataforma específica del sistema, especialmente algunos estándares en la parte inferior del sistema.
La biblioteca COM puede garantizar que todos los componentes interactúen de manera unificada. Nos permite usar directamente la API proporcionada por la biblioteca COM para programar sin escribir una gran cantidad de código básico necesario para la comunicación COM al escribir. Aplicaciones COM. Esto acelera enormemente el desarrollo. Por ejemplo, la versión de la biblioteca COM ahora admite componentes remotos, es decir, COM distribuido. Podemos comunicarnos entre programas en la red sin escribir ningún código de red o RPC (llamada a procedimiento remoto).
Si utilizamos un lenguaje orientado a objetos para implementar objetos COM, es natural utilizar clases para definir objetos. En lenguaje C, el concepto de objeto puede convertirse en un concepto lógico. Si existen dos objetos al mismo tiempo, entonces la implementación de la interfaz debe saber claramente para qué objeto es la operación. Este proceso se puede garantizar mediante la definición de la interfaz COM.
La idea de utilizar GUID para identificar objetos COM en la especificación COM se originó a partir del UUID (Universal LZ Unique Identifier) adoptado por OSF (Open Software Foundation). UUID se define como parte de DCE (entorno informático distribuido) y se utiliza principalmente para identificar a ambas partes en la comunicación RPC.
Además de la encapsulación y la reutilización, otra característica importante de los objetos C es el polimorfismo. Es el polimorfismo de los objetos C lo que refleja las características altamente abstractas del lenguaje C que usa clases para describir cosas. Los objetos COM también tienen polimorfismo, pero este polimorfismo sólo puede reflejarse a través de la interfaz del objeto COM, al igual que el polimorfismo de los objetos C sólo puede reflejarse a través de sus funciones (virtuales).
De API a interfaz COM
Si queremos implementar un sistema de aplicación de procesamiento de textos, necesitamos una función de búsqueda en diccionario. De acuerdo con el método de programación de componentes, naturalmente tenemos que colocar la función de búsqueda de diccionario en un programa de componentes (.dll). Si el algoritmo de búsqueda o la biblioteca de diccionario del programa de diccionario cambia en el futuro, el sistema de aplicación aún puede utilizar el nuevo programa componente siempre que la interfaz entre el programa de aplicación y el componente permanezca sin cambios. Ésta es la flexibilidad que conlleva el uso de programas de componentes.
Para conectar sistemas de aplicaciones y programas componentes y hacer que funcionen juntos, la forma más sencilla es definir un conjunto de funciones de búsqueda de diccionario, y este conjunto de funciones debe ser lo más general posible sin agregar una biblioteca de diccionario. funciones relacionadas.
Función
Declaración de función
Inicialización
Inicialización
Cargando biblioteca
Cargando Diccionario
Insertar palabra
Insertar una palabra
Eliminar palabra
Eliminar palabra
Buscar palabra
Buscar Word
Restaurar biblioteca
Almacena el diccionario en el archivo especificado en la memoria.
Biblioteca gratuita
Biblioteca de diccionarios publicados
La capa de interfaz API plana puede conectar bien los dos programas, pero existen algunos problemas como los siguientes:
(1) Cuando hay muchas funciones API, será muy incómodo de usar y es necesario organizar las funciones.
(2) Las funciones API deben estandarizarse y procesarse de manera uniforme para adaptarse a diferentes lenguajes de programación. Es necesario estandarizar el orden de paso de los parámetros, los tipos de parámetros y el procesamiento de retorno del clima frío y cálido.
COM define un conjunto completo de especificaciones de interfaz, que no solo pueden compensar las deficiencias de la API anterior como excusa de componente, sino que también aprovechan al máximo las ventajas de los objetos componentes y realizan el polimorfismo de objetos componentes.
Definición e identificación de interfaz
Técnicamente, una interfaz es una estructura de datos que contiene un conjunto de funciones a través de las cuales el código del cliente puede llamar las funciones de un objeto componente. La interfaz define un conjunto de funciones miembro, que son toda la información expuesta por el objeto componente, y el programa cliente utiliza estas funciones o los servicios del objeto componente.
El programa cliente llama a la función miembro de la interfaz con un puntero al mecanismo de datos de la interfaz. El puntero de la interfaz en realidad apunta a otro puntero, que apunta a un conjunto de funciones, llamado tabla de funciones de la interfaz (tabla de funciones virtuales). Cada elemento en la tabla de funciones de la interfaz es un puntero de función con una longitud de 4 bytes, y cada puntero de función está asociado con la implementación específica del objeto. De esta manera, siempre que obtenga el puntero de la interfaz, el cliente puede llamar a la función real del objeto.
Para una interfaz, se determina su tabla de funciones virtuales vtable, por lo que el número de funciones miembro de la interfaz permanece sin cambios y el orden de las funciones miembro permanece sin cambios para cada función miembro, sus parámetros y El; El valor de retorno también es seguro.
En la definición de la interfaz toda esta información debe determinarse a nivel binario. No importa qué idioma, puede admitir dicha descripción de la estructura de la memoria, es decir, puede admitir el tipo "estructura" o "registro", y este tipo puede contener miembros dobles que apunten a tablas de punteros de funciones y puede admitir la descripción de la interfaz, por lo que puede utilizarse para escribir componentes COM o utilizar componentes COM.
Lenguaje de descripción de interfaz
Basado en el uso de la especificación DCE de OSF para describir la interfaz de llamada remota IDL, la especificación COM se extiende para formar el lenguaje de descripción de interfaz COM.
El lenguaje de descripción de interfaz IDL utilizado en la especificación COM no solo se puede utilizar para definir interfaces COM, sino que también se puede utilizar para definir algunos tipos de datos de uso común y estructuras de datos definidas por el usuario. Para las funciones miembro de la interfaz, podemos especificar el tipo, las características de entrada y salida de cada parámetro, e incluso admitir la descripción de matrices de longitud variable. IDL admite tipos de puntero, similares a C/C.
Microsoft Visual C proporciona herramientas MIDL, que pueden compilar archivos de descripción de interfaz IDL en archivos de encabezado de descripción de interfaz compatibles con C/C (.h).
Definición de IUnknown (IDL):
Interfaz desconocida
{
Interfaz de consulta HRESULT([in]REFIID iid,[out ]void * * PPV);
ULONG AddRef(void);
ULONG Release(void);
}
IUnknown ( Definición de C):
Clase IUnknown
{
Público:
Interfaz de consulta virtual HRESULT _ stdcall ([in]ref iid iid, [out]void * * PPV) = 0;
Virtual ULONG _ stdcall AddRef(void) = 0
Virtual ULONG _ stdcall Release(void) = 0; /p>
}
Componente de trabajo en progreso
Dado que el componente en proceso y el programa cliente se ejecutan en el mismo espacio de direcciones de proceso, una vez que el programa cliente establece comunicación con el programa componente Relación, el puntero de interfaz obtenido por el programa cliente apunta a la tabla virtual de la interfaz en el programa componente. Esta vtable contiene las direcciones de todas las funciones miembro y el código del cliente puede llamar directamente a estas funciones miembro, por lo que es muy eficiente.
Debido a que el cliente carga el programa DLL en la memoria en tiempo de ejecución, el módulo DLL en sí es independiente y no depende del programa cliente.
En el lenguaje C, para hacer que el programa DLL compilado sea más versátil, el hábito de llamada de _stdcall generalmente se especifica para las funciones derivadas de la DLL. Si utiliza el hábito de llamar a _cdecl, algunos entornos de lenguajes de programación no pueden utilizar estos programas DLL. El compilador de C genera un nombre decorado para cada función del programa DLL. Estos nombres decorados son incompatibles con diferentes compiladores. Entonces, desde una perspectiva universal, ¿agregamos lo externo? c". especificador. En el entorno de desarrollo de Visual C, la siguiente declaración puede explicar bien una función derivada:
extern?c " int _ stdcall my function(int n);
En Para compilar un programa DLL, podemos seguir los siguientes pasos:
(1) Crear un proyecto DLL
(2) Para cada función de derivación, usar extern? c" y el modificador _stdcall, como se describió anteriormente para la función MyFunction.
(3) Según los métodos de programación tradicionales, también debemos escribir un archivo DEF para describir la información del módulo del programa DLL. En On En la plataforma Win32, podemos usar el descriptor _declspec(dllexport) directamente en la descripción de la función en lugar de usar un archivo DEF, por ejemplo:
extern? c " _ declspec(dll export)int _ stdcall my function (int n);
El módulo DLL creado de esta manera puede ser llamado por otros programas, porque el conector C conectará toda la información de la función derivada al código de destino final.
Desde el lado del cliente, hay tres funciones del sistema que se pueden utilizar para operar programas DLL, LoadLibrary, GetProcAddress y FreeLibrary.
En términos generales, el proceso de uso de un programa DLL sigue los siguientes pasos:
Primero, el programa cliente usa la función LoadLibrary para cargar la DLL y la DLL devuelve el identificador de instancia. del módulo para su uso futuro.
El programa cliente puede entonces llamar a la función GetProcAddress para obtener la dirección de la función derivada de la DLL. Podemos obtener la dirección de una función derivada a través del número de serie de la función (especificado en el archivo DEF) o el nombre de la función. Debido a que el programa cliente y el programa DLL están en el mismo espacio de direcciones de memoria, el programa cliente puede llamar directamente a estas funciones derivadas.
Finalmente, FreeLibrary descarga el programa DLL de la memoria para liberar recursos.
Descripción:
(1) Los programas DLL no solo pueden exportar funciones, sino también exportar variables globales. Debido a que el programa cliente y el programa DLL están en el mismo espacio de direcciones, tiene sentido exportar las variables globales en la DLL al programa cliente. El método de referencia no es complicado: coloque el nombre de la variable en la sección EXPORTACIONES del archivo DEF y agregue la opción DATOS o agregue el especificador _declspec (dllexport) antes de la descripción de la variable;
(2) DumpBin puede enumerar toda la información exportada en el programa DLL a través de la opción /Exportaciones.
(3) El programa cliente en sí también puede ser un programa DLL, pero primero debe cargarse en el espacio de proceso para que pueda llamar a funciones del sistema para ejecutarse como el módulo DLL del programa de servicio.
Componentes fuera de proceso
Debido a que el programa componente fuera de proceso y el programa cliente están ubicados en diferentes espacios de proceso y utilizan diferentes espacios de direcciones, la comunicación entre el componente y el cliente deben cruzar los límites del proceso, esto implica las siguientes preguntas:
¿Cómo llama un proceso a una función en otro proceso?
(2) ¿Cómo se pasan los parámetros de un proceso a otro?
En la plataforma Windows, existen muchos métodos de comunicación entre diferentes procesos, incluidos DDE, canalizaciones con nombre o * * * memoria compartida, etc. COM utiliza LPC (llamada a procedimiento local) y RPC (llamada a procedimiento remoto).
RegEdit puede verificar los objetos COM bajo la subclave CLSID (página 63)
Microsoft Visual C proporciona OleView.exe, que puede enumerar toda la información de categorías en la máquina actual y cada lista A. de objetos componentes bajo cada categoría.
regsvr 32D:\DIC comp\dict comp.dll
regsvr 32/u D:\DIC comp\dict comp.dll
El componente DLL está registrado Antes de ir a RegSvr32, debe haber dos funciones de entrada para el registro: DllRegisterServer y DllUnregisterServer.
COM estipula que los componentes fuera de proceso que admiten el autoregistro deben admitir los dos parámetros de línea de comando /RegServer y /UnregServer para completar la operación de registro o cierre de sesión.
Class Factory
De hecho, el programa cliente no llama directamente a la función exportada del programa componente, sino que llama a la función de la biblioteca COM para crear el objeto componente. La función de la biblioteca COM se basa en La información del registro llama a la función de entrada del programa componente para crear el objeto componente. Los programas de componentes deben proporcionar una función de entrada estándar DLLGetObjectClass para proporcionar información de componentes para este conjunto de programas.
Fábrica de clases y función DLLGetObjectClass
La fábrica de clases es la base para la producción de objetos COM. La biblioteca COM crea objetos COM a través de la fábrica de clases, existe para cada clase COM; una fábrica de clases dedicada a la operación de creación de objetos de clase COM.
La fábrica de clases en sí también es un objeto COM, que admite una interfaz especial: IClassFactory, definida de la siguiente manera:
Clase IClassFactory: pública IUnknown
{
Virtual HRESULT _ stdcall crear instancia (desconocido * punknouter, const IID & iid, void * * PPV) = 0
Virtual HRESULT _ stdcall LockServer(BOOL bLock) = 0; } ;
La interfaz IClassFactory tiene una función miembro importante CreateInstance, que se utiliza para crear el objeto COM correspondiente. Debido a que cada generador de clases es específico de un objeto COM específico, la función miembro CreateInstance sabe qué objeto COM crear. En los parámetros de la función miembro CreateInstance, el primer parámetro pUnknownOuter se usa al agregar objetos y se establece en NULL si no hay agregación. LockServer es otra función miembro de IClassFactory, que se utiliza para controlar el ciclo de vida del ensamblaje.
Debido a que el generador de clases en sí es un objeto COM y se utiliza en el proceso de creación de otros objetos COM, ¿quién creará el objeto del generador de clases? La respuesta es la función derivada DLLGetClassObject. La función DLLGetClassObject no es una función de la biblioteca COM, sino una función derivada implementada por el programa componente. Primero echemos un vistazo al prototipo de la función DLLGetClassObject:
HRESULT DLLGetClassObject(const CLSID & clsid,
Const IID & iid,
(void * *) ppv
);
Después de recibir la instrucción para crear el objeto, la biblioteca COM llamará a la función DLLGetClassObject del componente en proceso, que creará el objeto de fábrica de clases. y devuelve la clase El puntero de interfaz al objeto de fábrica. Una vez que la biblioteca COM o el cliente tiene el puntero de interfaz de la fábrica de clases, el objeto COM correspondiente se puede crear a través de la función miembro CreateInstance de la interfaz de la fábrica de clases IClassFactory.
Interacción entre la biblioteca COM y el generador de clases (página 67)
En la biblioteca COM, hay tres funciones API que se pueden usar para crear objetos, a saber, cogetclassobject, cocreateinstance y CoCreateInstanceEx. Normalmente, el cliente llama a uno de estos para completar la creación del objeto y devolver el puntero de interfaz inicial del objeto. Las bibliotecas COM y las fábricas de clases también interactúan a través de estas tres funciones.
¡La idea de que los componentes COM sean dlls es superficial!
DLL es una forma de distribución de componentes COM y también es un servidor de componentes.
¡Los componentes deben considerarse como un conjunto de interfaces implementadas en DLL!
DLL es una forma, el componente COM es la esencia.
Referencia:
/ella_Qing/blog/item/de 73 eef 8d 66 c 7d 0 DD 9 F9 FD 3 html