2010-02-22 6 views
10

Deseo recuperar programáticamente la ID de interfaz para cualquier clase para poder pasarla a CoCreateInstance. ¡¡Cualquier ayuda es muy apreciada!!¿Cómo recuperar la ID de la interfaz de una clase COM para que se pueda pasar a CoCreateInstance?

Ver "¿Cómo puedo obtener esta" continuación:

HRESULT hResult; 
CLSID ClassID; 
void *pInterface; 

if(!(hResult = SUCCEEDED(CoInitialize(NULL)))) 
{ 
    return 1; 
} 

if(S_OK == CLSIDFromProgID(OLESTR("Scripting.FileSystemObject"), &ClassID)) 
{ 
    hResult = CoCreateInstance(ClassID, NULL, CLSCTX_INPROC_SERVER, 
     <<How Do I Get This?>>, (LPVOID *)&pInterface); 
} 

CoUninitialize(); 

EDIT: Gracias por toda la ayuda, parece que funciona perfectamente ahora! :

HRESULT hResult; 
CLSID ClassID; 
IClassFactory *pClf; 
void *pVdb; 

if(!(hResult = SUCCEEDED(CoInitialize(NULL)))) 
{ 
    return 1; 
} 

if(SUCCEEDED(CLSIDFromProgID(OLESTR("Scripting.FileSystemObject"), &ClassID)) 
{ 
    IDispatch *pDispatch; 

    if(SUCCEEDED(CoCreateInstance(ClassID, NULL, CLSCTX_INPROC_SERVER, 
      IID_IDispatch, (void **)&pDispatch)) 
    { 
     OLECHAR *sMember = L"FileExists"; 

     DISPID idFileExists; 

     if(SUCCEEDED(pDispatch->GetIDsOfNames(
       IID_NULL, &sMember, 1, LOCALE_SYSTEM_DEFAULT, &idFileExists)) 
     { 
      unsigned int puArgErr = 0; 

      VARIANT VarResult; 
      EXCEPINFO pExcepInfo; 

      VariantInit(&VarResult); 
      VariantInit(&pExcepInfo); 

      DISPPARAMS pParams; 
      memset(&pParams, 0, sizeof(DISPPARAMS)); 
      pParams.cArgs = 1; 

      VARIANT Arguments[1]; 
      VariantInit(&Arguments[0]); 

      pParams.rgvarg = Arguments; 
      pParams.cNamedArgs = 0; 
      pParams.rgvarg[0].vt = VT_BSTR; 
      pParams.rgvarg[0].bstrVal = SysAllocString(L"C:\\Test.txt"); 

      hResult = pDispatch->Invoke( 
       idFileExists, 
       IID_NULL, 
       LOCALE_SYSTEM_DEFAULT, 
       DISPATCH_METHOD, 
       &pParams, 
       &VarResult, 
       &pExcepInfo, 
       &puArgErr 
      ); 

      SysFreeString(pParams.rgvarg[0].bstrVal); 

      printf("File Exists? %d\n", abs(VarResult.boolVal)); 
     } 

     pDispatch->Release(); 
    } 
} 

CoUninitialize(); 
+0

Sí, es difícil conseguir votos en las cosas de la "vieja escuela" más. ¡Pero al menos esto está aquí para que el próximo chico lo revise! : D – NTDLS

Respuesta

3

Es necesario saber por adelantado qué interfaz que pide. Esto se obtiene a partir de las especificaciones del producto, desde los archivos de encabezado SDK, o puede importar el TLB del objeto COM a su proyecto.

la forma easisest es utilizar #import

+0

Si tiene que saberse por adelantado, ¿cómo puedo escribir una DLL COM en C++ y usarla en ASP clásico a través de Server.CreateObject()? ASP clásico parece ser capaz de vincular a mi DLL y la interfaz con lo que me permite llamar funciones dentro de mi clase. – NTDLS

+1

Porque ASP solicita una interfaz bien conocida, IDispatch http://msdn.microsoft.com/en-us/library/ms221608.aspx –

+1

Exactamente. Usando la pregunta de mi respuesta: "¿Qué métodos de interfaz vas a invocar?" La respuesta es IDispatch, por lo que solicita esa interfaz desde CoCreateInstance. A continuación, utiliza los métodos de IDispatch para llamar a otros métodos cuyos nombres y parámetros no conocía en tiempo de compilación. –

2

plataforma SDK se distribuye con el código fuente de la utilidad Oleview, T contiene muy buen ejemplo para construir el árbol de todos los CLSID posibles y los nombres

3

Usted ya lo sabe. Va a ser el tipo de salida en tiempo de compilación que desea que la función almacene en la variable pInterface que le ha dado.

En otras palabras, ¿qué tipo de interfaz va a tratar el objeto que ha creado como? ¿Qué métodos de interfaz vas a invocar?

El tipo que obtienes de CLSIDFromProgID puede ser cualquier versión de la interfaz, incluida una que no existía en el momento de compilar el código. Por lo general, puede suponer que cualquier versión que esté disponible en tiempo de ejecución también admite alguna versión menor que conozca en tiempo de compilación. Le pide al sistema operativo que cree una instancia de la versión reciente, pero luego también le pide que devuelva una referencia a la interfaz de la versión menor, la que sabe cómo manejar.

La función llama QueryInterface en el objeto para usted, utilizando el tipo que ha solicitado, algo como esto:

obj->QueryInterface(riid, pInterface); 

Si no tienes nada más específica a la solicitud, sólo tiene que utilizar IUnknown.

Cuestiones relacionadas