Monografias.com > Computación > Programación
Descargar Imprimir Comentar Ver trabajos relacionados

DCOM y Visual C++



    Creación del servidor
    de Automatización OLE

    Creación del
    cliente

    Otros temas
    avanzados

    Sin duda, el entorno de trabajo en el
    que más horas he invertido en el pasado (miles de horas)
    ha sido Microsoft
    Visual C++. Simplemente me parece una obra maestra
    ….

    De vez en cuando me toca volver a él para hacer
    alguna cosilla y voy a aprovechar parra compartir con vosotros
    como se hacen (y no se hacen) algunas cositas, hoy relacionadas
    con el desarrollo de
    clientes y
    servidores de
    automatización OLE.

    Dando por echo que lo tenéis instalado y lo
    arrancamos. De una versión a otra cambian algunas cosas de
    aspecto pero los conceptos son los mismos.

    Creación del
    servidor de
    Automatización OLE

    Creamos un nuevo proyecto

    Elegimos una aplicación Visual C++ basada en un
    diálogo.
     El echo de que sea un diálogo solo es para que
    podamos ver que se arranca al ser invocado como un servidor de
    automatización y para que se registren todos los
    componentes en otra máquina con solo ejecutarlo (lo suyo
    sería crearlos como servidores ATL)

    Elegimos las opciones de configuración
    básica.

    No se os olvide pinchar la opción de
    automatización

     Revisamos los nombres de las clases que se van a
    generar  

    Vemos el aspecto de la aplicación y configuramos
    el diálogo con el editor de recursos 

     

     Debemos revisar los componentes creados, sobre
    todo el señalado (el interfaz) que en nuestro caso se
    llama Idombasico.

    Nota:

    Lo importante de la tecnología de componentes es que
    existe la definición de un interfaz que define
    un servicio a ofrecer (en el entorno
    Microsoft se hace todo tan automático que gente
    sin los conceptos claros puede trabajar
    cómodamente y los problemas vienen más
    tarde).

    Un componente en sí es solamente una
    implementación de ese interfaz (y algunos otros
    más).

    Una vez definido un interfaz, este
    JAMÁS se debe cambiar.

    Es una mala práctica ir
    añadiendo funciones a un interfaz a medida que lo
    necesitamos en un componente que lo
    implementa.

    Una vez que una aplicación está
    en producción, nunca se debe cambiar
    el interfaz sino crear uno nuevo (que lo amplíe
    o modifique) y por técnicas de agregación y/o
    composición construir un nuevo
    componente

     

    Añadimos a nuestro interfaz un
    método

    Decimos que retorne una cadena de
    caracteres 

    çç

     Y vemos como ha quedado el interfaz

    // dcombasico.idl: código fuente de la biblioteca de tipos para el archivo dcombasico.exe

    // El compilador MIDL procesará este
    archivo para generar

    // la biblioteca de tipos
    (dcombasico.tlb).

    [ uuid(645FB5A1-1591-4B8D-8FA9-1CBC0D1CC9A5),
    version(1.0) ]

    library dcombasico

    {

         
    importlib("stdole32.tlb");

         
    importlib("stdole2.tlb");

          // 
    Interfaz de envío principal para
    CdcombasicoDoc

         

          [
    uuid(DE8D669B-1D2A-41FA-A5A3-9BBA147F02C0) ]

          dispinterface
    Idcombasico

          {

               
    properties:

                     

               
    methods:

               
    [id(1), helpstring("method retornaHora")] BSTR
    retornaHora(void);

          };

          // 
    Información de clase para CdcombasicoDoc

         

          [
    uuid(65360127-D82B-484E-BC54-E6129CDF864C) ]

          coclass
    dcombasico

          {

               
    [default] dispinterface Idcombasico;

          };

    }; 

     El método se
    ha implementado en nuestra clase encargada de su
    implementación… que simplemente retorna la fecha

    BSTR CdcombasicoDlgAutoProxy::retornaHora(void)
    {
    AFX_MANAGE_STATE(AfxGetAppModuleState());

    CString strResult;

    // TODO: Add your dispatch handler code here
    CTime hora = CTime::GetCurrentTime();
    strResult = hora.Format("%d/%m/%Y");

    return strResult.AllocSysString();
    }
     

    Una parte de código que nos interesa …  el
    nombre necesario para crearlo por el cliente por
    nombre

    // La macro IMPLEMENT_OLECREATE2 se define en
    el archivo StdAfx.h de este proyecto

    //
    {65360127-D82B-484E-BC54-E6129CDF864C}

    IMPLEMENT_OLECREATE2(CdcombasicoDlgAutoProxy,
    "dcombasico.Application", 0x65360127, 0xd82b, 0x484e,
    0xbc, 0x54, 0xe6, 0x12, 0x9c, 0xdf, 0x86,
    0x4c)

     

    Creación
    del cliente

     Elegimos una aplicación Visual C++
    MFC

     Igualmente basada en diálogo

    Elegimos las opciones y no marcamos el soporte de
    automatización

    Pero para que funcione el ejemplo necesitamos
    añadir a mano estas líneas

    BOOL CclientedcomApp::InitInstance()

    {

               
    ……….

               
    // Inicializar bibliotecas OLE

               
    if (!AfxOleInit())

               
    {

                           
    AfxMessageBox("Error al incializar OLE");

                           
    return FALSE;

               
    }

     

     Creamos un diálogo básico

    Y revisamos que nuestro interfaz y servidor que lo
    implementa están registrados en el sistema
    ActiveX Control Test
    Container
    (en el menú Tools)

     Vemos el detalle

    Y el interfaz en el registro

    Ahora añadimos una clase nueva, pinchando el
    botón derecho del editor

    C

    reamos la clase desde un fichero
    descriptor 

    Elegimos el componente servidor

    Y revisamos el código generado

    Y añadimos el código al invocar el
    botón (no se os olvide incluir el .h):

    #include "Cdcombasico.h"

    void
    CclienteligeroDlg::OnBnClickedButton1()

    {

          // TODO: Add
    your control notification handler code here

         
    COleDispatchDriver disp;

          COleException
    *e = new COleException;

      

          try
    {

               
    // Create instance of Microsoft System Information
    Control

               
    // by using ProgID.

               
    if (disp.CreateDispatch("dcombasico.Application",
    e))

               
    {

                     
    Cdcombasico a = Cdcombasico(disp);

                     
    CString x = a.retornaHora();

                     
    AfxMessageBox("Todo ha funcionado " + x);

               
    }

               
    disp.DetachDispatch();

          }

          catch
    (COleDispatchException * e)

          {

               
    AfxMessageBox(e->m_strDescription);

               
    e->Delete();

          }

    Y ejecutamos.

    Veremos que todo funciona correctamente

    Otros temas
    avanzados

    Ojito con estos ejemplos…. la tecnología de
    componentes es algo serio y requiere formación y
    experiencia.

    Si miráis un poquito el código, en el
    servidor de automatización OLE se crea una cadena (que se
    sube a la memoria
    compartida) que se consume en el cliente ¿y quién
    la limpia? Este código generado desde el asistente,
    ¿dejará lagunas de memoria …. no
    detectable por el depurador?

    Os aconsejo que miréis este
    artículo

    http://www.codeguru.com/forum/showthread.php?t=231156

    y esta porción de código
    …..

    BSTR bstr;
       SomeOLEFunction(bstr);
       _bstr_t tmp(bstr, FALSE); //wrap the
    BSTR
       CString cs(static_cast<const char
    *>(tmp)); //convert it
       AfxMessageBox(cs, MB_OK, 0); //test
       // when tmp goes out of scope it will free
    the BSTRs memory

     Conclusiones

    Los entornos de desarrollo son cada día
    más potentes e impresionantes pero esto no quita para que
    realicemos un estudio profundo de las tecnologías base en
    las que se apoya.

    En la mayoría de las empresas, la
    gente utiliza los entornos de desarrollo de Microsoft por lo
    rápido que podemos ponernos en marcha…. los problemas
    vienen en ejecución  y cuando queremos ampliar la
    funcionalidad haciendo cosas que ya no nos hacen los asistentes
    (Wizards) automáticamente (por fallas graves de conceptos
    esenciales)…. pero bueno …. de algo tenemos que vivir los
    demás …..

     Roberto Canales Mora

    www.adictosaltrabajo.com

    Nota al lector: es posible que esta página no contenga todos los componentes del trabajo original (pies de página, avanzadas formulas matemáticas, esquemas o tablas complejas, etc.). Recuerde que para ver el trabajo en su versión original completa, puede descargarlo desde el menú superior.

    Todos los documentos disponibles en este sitio expresan los puntos de vista de sus respectivos autores y no de Monografias.com. El objetivo de Monografias.com es poner el conocimiento a disposición de toda su comunidad. Queda bajo la responsabilidad de cada lector el eventual uso que se le de a esta información. Asimismo, es obligatoria la cita del autor del contenido y de Monografias.com como fuentes de información.

    Categorias
    Newsletter