2010-02-22 20 views
10

我想編程式地檢索任何類的接口ID,以便我可以將它傳遞給CoCreateInstance。很感謝任何形式的幫助!!如何檢索COM類的接口ID,以便它可以傳遞給CoCreateInstance?

請參閱「我如何獲得這」下面:

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(); 

編輯:感謝所有的幫助下,現在似乎很好地工作! :

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

是的,它很難得到「老派」的東西投票了。但至少這是在這裏爲下一個人審查! :D – NTDLS 2010-02-23 01:04:53

回答

3

你需要知道的前期你問什麼接口。這可以從SDK頭文件的產品規格中獲得,也可以將COM對象的TLB導入到項目中。

的easisest方法是使用#import

+0

如果必須事先知道,那我該如何在C++中編寫COM DLL,並通過Server.CreateObject()在Classic ASP中使用它?經典的ASP似乎能夠綁定到我的DLL和接口,讓我可以在我的班級內調用函數。 – NTDLS 2010-02-22 19:27:04

+1

因爲ASP要求一個良好的知識接口,IDispatch http://msdn.microsoft.com/en-us/library/ms221608.aspx – 2010-02-22 19:28:18

+1

沒錯。使用我的答案中的問題:「你打算使用哪種接口的方法?」答案是IDispatch,所以您需要從CoCreateInstance獲取該接口。然後,您可以使用IDispatch的方法在編譯時調用其名稱和參數不知道的其他方法。 – 2010-02-22 19:35:17

2

平臺SDK一起發行OLEVIEW工具的源代碼,T包含相當不錯的例子,構建所有可能的CLSID的樹和他們的名字

3

你已經知道了。這將是編譯時間輸出類型,您希望該函數存儲在您給出的pInterface變量中。

換句話說,你將要用什麼接口類型來對待你創建的那個對象?您將調用哪個接口的方法?

您從CLSIDFromProgID獲得的類型可能是接口的任何版本,包括在編譯代碼時甚至不存在的類型。您通常可以假定在運行時提供的任何版本也支持您在編譯時知道的較低版本。你要求操作系統實例化最近版本的一個實例,但是你也要求它返回一個引用到較低版本的接口 - 你知道如何處理的接口。

功能爲你的對象調用QueryInterface,使用您所請求的類型,像這樣:

obj->QueryInterface(riid, pInterface); 

如果你有什麼更具體的要求,只要使用IUnknown

相關問題