1 / 43

Ingeniería del software II

ISBC Component Object Model (COM). Ingeniería del software II. Introducción. COM es un modelo de componentes binario que puede ser utilizado con independencia del lenguaje de programación Los sistemas Windows de Microsoft están basados en componentes COM

tarak
Download Presentation

Ingeniería del software II

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. ISBC Component Object Model (COM) Ingeniería del software II

  2. Introducción COM es un modelo de componentes binario que puede ser utilizado con independencia del lenguaje de programación Los sistemas Windows de Microsoft están basados en componentes COM Dentro de un sistema Windows existen diversos componentes realizados con esta tecnología: Menús contextuales (ej: menú de selección de fichero) DirectX Diversas aplicaciones de Microsoft Office

  3. Introducción La tarea de creación de este tipo de componentes es compleja, normalmente se emplea la librería de plantillas Active Template Library para facilitar esta tarea La librería ATL es un conjunto de clases de C++ basadas en plantillas que facilitan la creación de objetos del modelo COM Algunos IDE’s como Visual C++ o Borland Builder C++ disponen de asistentes que nos facilitan la creación de componentes COM

  4. Introducción Diferencias entre un objeto COM y un objeto C++: los objetos en C++ siempre se ejecutan en el mismo proceso. Los objetos COM pueden ejecutarse estando el cliente en otro proceso que el servidor, o incluso en otro ordenador En C++ es el cliente el que asigna la memoria para el objeto. En un objeto COM, al poder crearse objetos remotamente debe de existir un mecanismo para la creación del objeto a distancia Los nombres de las clases de C++ deben de ser únicos en el proceso mientras que los nombres de los componentes COM deben ser únicos en el mundo

  5. Modelo Cliente/Servidor El uso de los componentes COM es un claro ejemplo de la arquitectura Cliente/Servidor. El objeto COM en sí es el servidor, y es usado por un programa que hace de cliente. El servidor COM lo podemos encontrar de varias formas: Como partes de un ejecutable Dentro de una librería de enlace dinámico En otra máquina ( DCOM )

  6. Identificación del servidor Se nos presenta un problema a la hora de identificar que componente queremos usar cuando el componente reside en un lugar distinto al cliente Una posible forma de hacerlo sería con un nombre. Sin embargo esto no es factible, 2 programadores distintos podrían usar el mismo nombre para componentes distintos Para identificar cualquier "cosa" que necesite unicidad, microsoft utiliza una secuencia de 128 bits

  7. Identificación del servidor con 128 bits la posibilidad de conflicto es prácticamente nula Para conseguir que estas secuencias no se dupliquen Microsoft proporciona un mecanismo que genera un número aleatorio, lo mezcla con información del equipo que ejecuta la función, etc ... Esta secuencia se llama GUID , estos GUID’s pueden usarse para identificar otros elementos como drivers o dispositivos, Los GUID’s utilizados para identificar objetos COM, se denominan CLSID

  8. Interfaces El cliente nunca va a poder tratar con el objeto directamente. Tendrá que hacerlo a través de sus interfaces. El cliente tendrá un puntero a esa interfaz y podrá llamar a los métodos que declara la propia interfaz Cada interfaz es una tabla virtual (vtable o vtbl) de funciones a través de las cuales se accede a la implementación en el componente COM

  9. Interfaces Los clientes no almacenan en memoria el objeto COM sino una vtable por cada interfaz del componente para acceder a sus métodos, reduciendo de este modo el uso de memoria en el sistema

  10. Interfaces Las interfaces también tiene un GUID ( denominado IID, o identificador de interfaz ). Un mismo objeto COM puede implementar varias interfaces Las interfaces de un COM son inmutables. Cuando sea necesario añadir o modificar algún método de una interfaz se creará una interfaz nueva, de este modo aseguramos que los clientes que usarán esta interfaz antes de ser modificada sigan funcionando correctamente.

  11. Interfaces Reutilización de Interfaces: determinados conjuntos de operaciones pueden ser implementados por distintos componentes. Varios componentes pueden proveer funciones para la lectura y escritura de streams de bytes, en este caso implementarán la interfaz IStream. Transparencia para llamadas remotas y locales. Una vez obtenido el puntero a la interfaz la forma de realizar las llamadas será exactamente la misma para componentes locales y para componentes remotos.

  12. Interfaces COM debe ser independiente del lenguaje, debe existir al menos un lenguaje neutro para definir las estructuras, las funciones y los propios objetos. Microsoft utiliza una variante del IDL empleado por RPC ( Remote Procedure Call ) orientado a objetos. A partir de este lenguaje sería posible obtener las declaraciones en distintos lenguajes de programación para que pudieran ser usados Todas las interfaces definidas en un componente COM derivan de IUnknow, Cuando el usuario crea un objeto, obtiene un puntero a la interfaz IUnknown. Esta interfaz deberá proporcionar las funciones necesarias para poder usar otra interfaz

  13. Interfaces Interfaz IUnknow en IDL: interface IUnknown { HRESULT QueryInterface ( [in]REFIID riid, [out,iid_is(riid)] void **ppvObject); ULONG AddRef(); ULONG Release();}

  14. Interfaces QueryInterface sirve para pedir un puntero a otra interfaz del mismo objeto. Se le pasan dos parámetros, el primero es el IID (identificador de interfaz) de la interfaz que queremos obtener, y de segundo parámetro un puntero a puntero a esa interfaz Los métodos AddRef() y Release() sirven para controlar el ciclo de vida del objeto COM. Cuando un objeto no este referenciado el mismo se encargará de borrarse

  15. Interfaces Componente COM y sus interfaces:

  16. Tipos de servidores COM Servidores COM en DLL: Esta es la forma más habitual de funcionamiento del modelo COM, cliente y servidor comparten un espacio de direcciones y un mapa de memoria, es decir, se ejecutan en el mismo proceso (in-process) El paso de parametros se realiza por los mecanismos habituales de paso de parametros para DLL's,esto se realiza de forma transparente para el programador Es el programa cliente el que realiza la creación de memoria para comenzar la creación del objeto COM. Al entrar en ejecución el constructor del objeto, éste podría realizar peticiones de memoria dinámica

  17. Tipos de servidores COM Servidor COM en un ejecutable (.exe) Son llamados servidores locales. Se ejecutan en el mismo ordenador que el cliente, pero en procesos distintos. La comunicación la gestiona el sistema operativo. No hace falta que esté el ejecutable del servidor funcionando, pues el sistema es capaz de ejecutarlo. El ejecutable contiene una parte que se encarga de la gestión de memoria inicial que requieren los objetos COM

  18. Tipos de servidores COM Servidor COM remoto Cliente y servidor se encuentran en ordenadores distintos. La comunicación la gestiona el sistema operativo. Internamente, Microsoft usa el protocolo RPC para realizar la comunicación. Sin embargo, el programa servidor debe de estar ejecutándose. A la hora de la práctica, hay poca diferencia en la programación. Las funciones miembro se llaman de la misma forma, los objetos se crean prácticamente igual con la salvedad de que en este caso es necesario indicar el ordenador (host) donde se encuentra el servidor com remoto.

  19. Tipos de servidores COM Servidor COM remoto Un componente COM al que se accede de forma remoto se denomina DCOM (Distribuited COM) El módelo binario de DCOM se encarga de todos los detalles referentes a la comunicación remota, empaqueta los parametros a enviar y se encarga de recibir los parametros y devolverlos de la forma en que los espera el cliente. De este modo se consigue la transparencia de llamadas ya este el componente en local o en remoto

  20. Reutilización en COM • En los componentes COM no existe el concepto de herencia, para la reutilización se utiliza COMPOSICION o AGREGACIÓN. • En la COMPOSICION el objeto COM simplemente actuá a su vez como cliente del objeto COM que contiene.

  21. Reutilización de COM • En la agregación se expone directamente la interfaz del objeto COM agregado, de modo que el cliente puede acceder de forma transparente a las interfaces de los dos objetos COM.

  22. COM+ COM+ es una ampliación al modelo de componentes COM para la construcción de aplicaciones empresariales, se encarga de proporcionar una serie de servicios: Seguridad de grano fino, controla el acceso a cada método. Escalabilidad, mediante balanceo de carga y “object pooling” Manejo de transacciones, a través de MTS (Microsoft Transactional server)

  23. Ejemplo de implementación • En este ejemplo se va a construir un objeto COM capaz de almacenar la siguiente información sobre un usuario: • Age -> short • Name -> LPSTR • Sex -> unsigned char • El objetivo de este ejemplo es poner de manifiesto cuales son las tareas básicas de las que es responsable todo objeto COM.

  24. EJ: Tareas del COM • Crear los GUID’s necesarios para el objeto y sus interfaces • Definir las interfaces del objeto • Implementar las funciones de la interfaz definida • Registrar el servidor COM

  25. EJ: Crear los GUID’s • El API COM dispone del método CoCreateGuid que se encarga de esta tarea. • Como parte de la distribución de VS se puede encontrar el programa UUIUDGEN.exe para realizar esta tarea, aunque internamente sencillamente llama al método del API anterior. Generamos los 3 GUID’s que vamos a necesitar: • C:>uuidgen -n3 acceeb00-86c7-11d0-94ab-0080c74c7e95 acceeb01-86c7-11d0-94ab-0080c74c7e95 acceeb02-86c7-11d0-94ab-0080c74c7e95

  26. EJ: Definir las Interfaces • Definición de la interfaz IUserInfo import "unknwn.idl" ; [ object, uuid(acceeb02-86c7-11d0-94ab-0080c74c7e95) ] interface IUserInfo : IUnknown { [propget] HRESULT Age([out, retval] short *nRetAge); [propput]HRESULT Age([in] short nAge); [propget]HRESULT Name([out, retval] LPSTR *lpszRetName); [propput]HRESULT Name([in] LPSTR lpszName); [propget]HRESULT Sex([out, retval] unsigned char *byRetSex); [propput]HRESULT Sex([in] unsigned char bySex); }

  27. EJ: Definir las Interfaces • Definición de la type library y del objeto UserInfo [ uuid(acceeb00-86c7-11d0-94ab-0080c74c7e95),version(1.0) ] library UserInfo { [ uuid(acceeb01-86c7-11d0-94ab-0080c74c7e95), ] coclass UserInfo { [default] interface IUserInfo; } }

  28. EJ: Implementación de la interfaz • Las interfaces en IDL creadas las compilamos a través de MIDL (incluido en VS) y se obtienen los siguientes ficheros: UserInfo_i.h IDL MIDL UserInfo_i.c

  29. EJ: Implementación de la interfaz • Contenido de UserInfo_i.c const IID IID_IUserInfo = {0xacceeb02,0x86c7,0x11d0, {0x94,0xab,0x00,0x80,0xc7,0x4c,0x7e,0x95}}; const CLSID CLSID_UserInfo = {0xacceeb01,0x86c7,0x11d0, {0x94,0xab,0x00,0x80,0xc7,0x4c,0x7e,0x95}}; const IID LIBID_UserInfo = {0xacceeb00,0x86c7,0x11d0, {0x94,0xab,0x00,0x80,0xc7,0x4c,0x7e,0x95}};

  30. EJ: Implementación de la interfaz • Contenido de UserInfo_i.h • Este fichero contiene las cabeceras del interfaz tanto en C como en C++ • La interfaz en C++ se declara como una clase abstracta con todos sus métodos virtuales puros, de esta manera se fuerza a quien implemente la interfaz a implementar todos sus métodos. class IUserInfo { public: virtual QueryInterface(REFIID iid, LPVOID *ppv) = 0; .............}

  31. EJ: Implementación de la interfaz class CUserInfo : IUserInfo { private: ULONG m_cRef; private: short m_nAge; private: LPSTR m_lpszName; private: BYTE m_bySex; public: STDMETHODIMP QueryInterface(REFIID iid, LPVOID *ppv); public: STDMETHODIMP_(ULONG)AddRef(void); public: STDMETHODIMP_(ULONG)Release(void); public: STDMETHODIMP get_Age(short *nRetAge); public: STDMETHODIMP put_Age(short nAge); public: STDMETHODIMP get_Name(LPSTR *lpszRetName); public: STDMETHODIMP put_Name(LPSTR lpszname); public: STDMETHODIMP get_Sex(BYTE *byRetSex); public: STDMETHODIMP put_Sex(BYTE bySex); CUserInfo(); ~CUserInfo(); }; IUnknow IUserInfo

  32. EJ: Implementación de la interfaz • Implementación del método QueryInterface STDMETHODIMP CUserInfo::QueryInterface(REFIID iid, LPVOID *ppv) { *ppv = NULL; if (IID_IUnknown == iid) *ppv = (LPVOID)(IUnknown *)this; else if (IID_IUserInfo == iid) *ppv = (LPVOID)(IUserInfo *)this; else return E_NOINTERFACE; //Interface not supported ((IUnknown *)*ppv)->AddRef(); return NOERROR; }

  33. EJ: Implementación de la interfaz • Implementación del método AddRef STDMETHODIMP_(ULONG) CUserInfo::AddRef(void) { return ++m_cRef; }

  34. EJ: Implementación de la interfaz • Implementación del método Release STDMETHODIMP_(ULONG)CUserInfo::Release(void) { m_cRef-; if (0 == m_cRef) { delete this; g_cObjects-; if (::ServerCanUnloadNow()) ::UnloadServer(); return 0; } return m_cRef; }

  35. EJ: Implementación de la interfaz • Una vez implementados los métodos de la interfaz Iunknow simplemente restaría implementar el resto de métodos de la clase CUserInfo, los que corresponden a la interfaz IUserInfo. • La implementación de estos métodos es trivial, consiste únicamente en establecer y devolver los valores de las propiedades definidas para contener el sexo, nombre y edad del usuario.

  36. EJ: Registrar el servidor COM • La información sobre el objeto COM debe estar en el registro de windows para que los clientes puedan localizarlo, la especificación COM define que las dll’s que contengan objetos COM deben implementar los siguientes métodos para esta tarea: • DllRegisterServer – En esta función se escribirá la información necesaria en el registro para que luego se pueda localizar el servidor COM. • DllUnregisterServer – Esta función es la encargada de borrar la información sobre el COM escrita en el registro.

  37. EJ: Registrar el servidor COM • La información que se debe almacenar en el registro sobre el servidor COM es la siguiente: HKEY_CLASSES_ROOT CLSID {acceeb01-86c7-11d0-94ab-0080c74c7e95} = Description InprocServer32 = C:\UserInfo\UserInfo.dll • Los programas como Regsrv32.exe que se utilizan para registrar objetos COM simplemente cargan la dll y invocan el método DllRegisterServer

  38. EJ: Creación de un cliente • El cliente debe realizar las siguientes tareas: • Iniciar la librería COM • Obtener la interfaz • Manipular el objeto a través de su interfaz • Liberar las interfaces • Finalizar la librería COM

  39. EJ: Iniciar la librería COM • Para iniciar la librería COM hay que llamar al método del API COM CoInitialize: hr = CoInitialize(NULL); if ( SUCCEEDED(hr) ) { ... } • El método CoInitialize inicializa la librería en el thread de ejecución desde el que se invoque. Es necesario llamar a CoInitialize desde cada thread de la aplicación que quiera acceder a objetos COM.

  40. EJ: Obtener la interfaz • Para obtener la interfaz inicial llamamos al método CoCreateInstance, este creará una nueva instancia de un objeto COM y nos devolverá un puntero a su interfaz. IUnknown *pIUnknown = NULL; hr = CoCreateInstance(CLSID_UserInfo, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (LPVOID *)&pIUnknown); if (SUCCEEDED(hr)) {....}

  41. EJ: Obtener la interfaz • A través del puntero a IUnknow obtener el puntero a la interfaz IUserInfo hr = pIUnknown->QueryInterface(IID-IUserInfo, (LPVOID *)&pIUserInfo); if (SUCCEEDED(hr)) {\\manipulación del objeto}

  42. EJ: liberar las interfaces • Para liberar las interfaces hay que llamar al método Release, si el objeto COM no tiene más interfaces referenciadas se borrara automaticamente: pIUserInfo->Release(); pIUnknown->Release();

  43. EJ: Finalizar la librería COM • La librería COM se finaliza a través del método CoUninitialize, una vez llamado a este método no se podrá seguir llamando a funciones de la librería COM ni manipulando objetos COM.

More Related