La Web del Programador: Comunidad de Programadores
 
    Pregunta:  16345 - LLAMAR UN COMPONENTE (DLL) DESDE UN EXE CREADO EN VISUALC++
Autor:  Monica Covarrubias
Hola :
Por favor si pueden contestar esta pregunta
estoy trabajando con herramientas
Visual C++ versiòn enterprise, SQL Server 7.0, WinNT, MTS. Estoy
desarrollando una aplicaciòn Cliente - servidor, la cual me permita tener
acceso a la BD ubicada en el Servidor, por lo tanto necesito crear componentes
(dll). Ya he creado dll`s, es decir componentes desde Visual C y Visual Basic,
ahora necesito implementarla con la interfaz de usuario (.exe), pero solo lo
he podido lograr desde Visual Basic, mi pregunta es:
¿còmo podrìa utilizar dichas sentencias de còdigo que manejo en VisualBasic, que sean las aquivalentes a visual C++?
ya que por otras razones me requieren que maneje una sola herramienta de desarrollo que es Visual c,tanto para
crear los componetes que tendràn conexion con la BD, y para la interfaz de usuario (.exe) que seràn
instalados en los clientes.

La sentencia de còdigo que utilizo en VisualBasic es la siguiente:

Private Sub Command1_Click()

Dim x As ComponneteLib.interface

Set x = CreateObject("Componnete.interface")

End Sub

Asì es como llamo al componente creado en Visual C

Como utilizo el equivalente a Visual C para llamar al componente desde mi (.exe) tambien desarrollado en VisualC
dicho ejecutable es una aplicacion basada en Dialogo.

Espero puedan ayudarme, ya que por el momento no he podido continuar con el desarrrollo de mi proyecto
Si requieren mayor informaciòn, no duden en solicitarmela.

Hasta pronto
Espero Respuesta

Monica Covarrubias L.

  Respuesta:  Jesús Antón Martín
Te has metido en un buen embrollo.

El manejo de componentes COM en VC++ es considerablemente complejo.

Desde luego es menos complejo que desde C, donde uno tiene que poner las llamadas con el protocolo correcto a mano, pero aún así, es mucho más complejo que en VB.

Para crear una instancia de un interfaz en VC++ tienes que usar el API de Win32, empezando por "CoInitialize" o "CoInitializeEx" (espero que tengas la documentación instalada), o bien puedes escoger llamar a OleInitialize (que llamará a CoInitializeEx). En cualquier caso, debes luego (cuando hayas terminado) llamar a CoUninitialize u OleUninitialize respectivamente.

Posteriormente necesitarás usar la función "CoGetClassObject", aunque puedes encontrar más fácil usar "CoCreateInstanceEx" y luego utilizar "QueryInterface" sobre el interfaz que proporciona para obtener tu instancia.

Para deshacerte de las instancias que ya no usas, llamarás a "Release" sobre cada interfaz que has recuperado. Si no lo haces, el servidor no se descargará de la memoria.

ejemplo:

...
OleInitialize(NULL);
if ((CoGetClassObject(
MyClass_REFCLSID,
CLSCTX_INPROC_SERVER,
NULL,
MyClass_REFIID,
LPVOID(MyClass_Ptr)
) == S_OK) {
MyClass_Ptr->DoWhatEverWeNeed();
MyClass_Ptr->Release();
}
OleUninitialize();
...

Este ejemplo no ha sido comprobado de ninguna forma, pero según la documentación debería funcionar.

Ha sido creado usando SOLO el API de Win32 para COM. Si esto es un problema, investiga en la MSDN cómo solventarlo ;).

Un saludo.