來新公司學習接手新項目,拿到代碼打開解決方案看到裡面竟然有40幾個工程,有點吃驚。具體看代碼也有很多之前沒見過的寫法,上了幾天火。
有件事就沒太搞明白,按照文檔的說法上層很多軟體都要調用IO伺服器,但看程式安裝目錄,IO伺服器其實是一個exe程式,按照我之前的印象,能被别的程式調用的也得是動态庫、靜态庫或者服務。實在想不通exe程式怎麼作為接口被别的程式調用的。
結果昨天研究了一天,想通了,這個IO伺服器其實就是COM元件。
按照網上的說法:COM component(COM元件)是微軟公司為了計算機工業的軟體生産更加符合人類的行為方式開發的一種新的軟體開發技術。在COM構架下,人們可以開發出各種各樣的功能專一的元件,然後将它們按照需要組合起來,構成複雜的應用系統。由此帶來的好處是多方面的:可以将系統中的元件用新的替換掉,以便随時進行系統的更新和定制;可以在多個應用系統中重複利用同一個元件;可以友善的将應用系統擴充到網絡環境下;COM與語言,平台無關的特性使所有的程式員均可充分發揮自己的才智與專長編寫元件子產品。
COM元件可以是dll或者exe或者服務的形式。
按照這個思路,代碼就看懂了不少,之是以解決方案裡有那麼多工程,也不過是因為劃分了很多動态庫和COM元件。
又花了些時間,寫了個小程式來實作最簡單的exe形式COM元件的生成與調用,如下:
首先建立一個ALT工程:

在類視圖裡,為工程添加ALT的類,和接口:
這裡定義了類,和對應的接口(Interface),注意ProgID要寫,待會程式調用com接口時,要通過ProgID找com元件
之後項目目錄如下,在.idl檔案裡有com接口(interface),裡面還定義了com元件的id等等不贅述了,實作類在ATLTest.cpp裡,其對應關系都是vs自動搭建的。
接下來還是在類視圖裡具體添加方法(接口和實作):
方法内部寫程式,邏輯是兩數求和:
STDMETHODIMP CCATLTest::ATLTestFunc0(SHORT num1, SHORT num2, SCODE* pRetNum)
{
*pRetNum = num1 + num2;
return S_OK;
}
然後編譯會出錯,那是因為執行com元件注冊指令時候,缺乏管理者權限,
重新啟動vs,以管理者權限運作即可。
接下來建一個mfc項目,這不是今天主題就不贅述了,
在界面上簡單填個按鈕和輸入框,寫個兩數求和的圖形界面demo,
具體的求和的方法要調用com元件。
mfc項目裡添加com接口,在類向導裡選擇添加類,選atl,選TypeLib中的MFC類:
之後可以選取前面定義的Lib:
加入COM接口檔案後,就可以調用了,注意我下面的寫法:
void CATLMfcClientDlg::OnBnClickedGetRetButton()
{
CoInitialize(NULL);
CATLTest myCom;
if (!myCom.CreateDispatch(_T("ATLTest.math.1")))
{
MessageBox(L"元件注冊失敗");
return;
}
CString strNum1,strNum2;
// 擷取使用者輸入的數字
this->numInput1.GetWindowTextW(strNum1);
this->numInput2.GetWindowTextW(strNum2);
// 調用COM接口,兩數求和
short ret = myCom.ATLTestFunc0(_wtoi(strNum1),_wtoi(strNum2));
WCHAR buf[50];
_itow(ret,buf,10);
// 顯示結果
this->numRet.SetWindowTextW(buf);
CoUninitialize();
return;
}
運作效果:
上面有說的簡略的地方,具體可以看我上傳git的源碼:
https://github.com/SonnAdolf/MyAtlExeComDemo
額外内容:
動态連結庫和COM元件的差別
1動态連結庫的表現形式隻能是dll[變态該名的除外], COM元件的表現形式可以是dll也可以是exe。
注:其實字型、驅動等也算是動态連結庫的一種,這裡略去...
2 動态連結庫的生成和編譯器及系統相關,在Windows/Linux下系統,需要分别編譯才能使用。
COM元件是二進制編碼,在Windows和Linux下可以直接使用,不需要重新編譯。
3 COM元件是按照COM規範實作的dll或者exe;動态連結庫是一個可以導出函數的函數集合。
4 動态連結庫隻能在本機被調用,COM元件支援分布式使用。
轉載于:https://www.cnblogs.com/rixiang/p/11491840.html