接觸COM組件不久,按照網上教程用ATL模板弄了個COM組件,創建了類,添加了方法并注冊。然后用MFC寫了可執行程式呼叫COM組件介面的方法(函式),跑通沒問題。
專案的要求是我要做一個通用的檢測軟體,測驗多個廠家的COM組件。這些COM組件都是按照行業某規范提供一組函式介面,函式名和引數都規定好的,各廠家一致,內部實作不同。
我希望用一個檢測軟體,運行時選擇不同廠家的那個dll檔案,就能呼叫到這廠家COM組件介面的函式。那么首先各廠家COM dll檔案的檔案名是不確定的,#import ****.dll no_namespace 這里是否有麻煩? 更重要的是,各廠家COM組件中的類的名字不確定,無法在撰寫測驗軟體時匯入,網上搜到的呼叫方法有:
CLSIDFromProgID(OLESTR("myCom.GetRes"),&clsid);
CComPtr<IGetRes> pGetRes; //智能指標 實際情況IGetRes不確定
pGetRes.CoCreateInstance(clsid);
pGetRes->Hello();
ProgID 等資訊也許還可以查,測驗程式運行時傳進去,但 IGetRes 這個類介面名測驗程式編譯時就定了,運行時改不了。
如果各廠家COM組件類介面名,檔案名現在都未知,那這個辦法還行得通嗎?應該如何動態呼叫呢?
uj5u.com熱心網友回復:
學會使用OleView.exeuj5u.com熱心網友回復:
謝謝!
運行OleView.exe能看到已注冊的COM組件的資訊,
但是撰寫上層測驗程式時還沒有獲得COM組件檔案,不知道第三方COM組件的類介面名,代碼就不好寫。
比如
HRESULT hr=CLSIDFromProgID(OLESTR("myCom.GetRes"),&clsid);
IGetRes *ptr;
hr=CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER,
__uuidof(IGetRes),(LPVOID*)&ptr);
這種呼叫方法,沒有獲得COM組件檔案前,IGetRes 這個名字都還不知道,怎么解決呢?
uj5u.com熱心網友回復:
介面都是基于 IDispatch 的嗎?dll 內是否包含了型別庫呢?
uj5u.com熱心網友回復:
第三方庫都需要檔案等來描述,這樣也就是所謂的SDKuj5u.com熱心網友回復:
我自己弄得COM組件介面是基于IDispatch 的。
現在在研究QueryInterface然后invoke的辦法能不能繞開這個介面名,剛接觸不懂得太多了。
其他廠商的COM怎么弄得我就不知道了。
uj5u.com熱心網友回復:
如果有型別庫,可以得到所有資訊,如果是 IDispatch ,無需頭檔案就可以呼叫uj5u.com熱心網友回復:
我給你提供一個方式。我們當年有一個要求,根據不同的硬體來呼叫不同的 COM。類似于硬體的驅動,但是不是驅動。
每一類設備向程式提供自己需要的 COM 的 CLSID。
根據這個 CLSID 直接創建實體,回傳介面。
以后使用這個介面,就和具體是那個 COM 就無關了。
uj5u.com熱心網友回復:
對,我的應用環境跟您說的很像!各家廠商的COM組件與各自的硬體通信,我寫檢測軟體分別呼叫他們。
問題現在不知道有幾家廠商(也許陸續增加)也不知他們組件的介面名字。有些東西可以在檢測軟體運行時去獲取,比如CLSID,介面的IID,但是檢測軟體編程時,好像必須知道介面名字,不然CComPtr<IGetRes> pGetRes; 或者IGetRes *ptr; 這樣的代碼不好寫,也無法正確通過虛函式表呼叫函式。
您說的“”從CLSID直接創建實體,回傳介面“” ,是回傳介面的指標還是什么?光有介面指標不知道介面名字,無法實體化去訪問其成員函式吧?能否再說詳細一些
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/108140.html
