1、打開VS2010,新建ATL COM 項目,步驟:“文件” --》“新建” --》“項目”,選擇“Visual C++” --》“ATL 項目” ,填寫“名稱” FirstCOM --》“確定”。
2、ATL 項目嚮導,勾選 【支持COM+ 1.0】和【支持部件註冊器】,其他默認,點擊完成。
3、切換到類視圖,右鍵單擊項目“FirstCOM”--》“添加” --》“類”。
4、選“ATL” --》“ATL 簡單對象” --》“添加”。
5、ATL 簡單對象嚮導,“簡稱”中輸入類名稱FirstClass,其他輸入框會自動填寫,最下面的“ProgID”沒有自動填寫,最好自己寫上一個,如FirstCOM.math,否則後面無法正確調用組件,點擊“完成”。如果出現提示【是否覆蓋現有文件】,點擊【是】即可。
6、切換到類視圖,選中剛纔添加的接口IFirstClass,如下,然後右鍵單擊【添加】添加方法。
7、添加方法嚮導,在"方法名" 下輸入Add。增加兩個輸入參數:勾選【in】,選擇參數類型LONG,輸入參數名para1,點擊“添加”。同樣操作增加參數para2。然後增加一個返回參數:先選擇參數類型LONG*,再勾選【retval】,輸入參數名result,點擊添加。點擊“完成”即可,如果點擊下一步,不需要填寫信息,點擊“完成”即可。
8、切換到解決方案資源管理器,展開項目“源文件”, 雙擊 FirstCom.idl 打開IDL定義文件,看到如下代碼,就是定義的COM方法了。
9、雙擊打開FirstClass.cpp 編輯代碼:*result = para1 + para2
- #include "stdafx.h" #include "FirstClass.h"
- // CFirstClass
- STDMETHODIMP CFirstClass::Add(LONG para1, LONG para2, LONG* result)
- {
- // TODO: 在此添加實現代碼
- *result = para1 + para2;
- return S_OK;
- }
<span style="font-size:14px;">#include "stdafx.h" #include "FirstClass.h"
// CFirstClass
STDMETHODIMP CFirstClass::Add(LONG para1, LONG para2, LONG* result)
{
// TODO: 在此添加實現代碼
*result = para1 + para2;
return S_OK;
}
</span>
10、編譯運行,會生成dll文件,並自動註冊到系統中。
問題及解決方法
問題1:我在Win64位系統中編譯的,出現錯誤:無法打開預編譯頭文件:“Debug\FirstCOM.pch”:No such file or directory。
解決:右鍵點擊你創建的項目,選擇“屬性”,彈出“FirstCOM 屬性頁”,在左側展開"配置屬性"--》展開“C/C++”--》選中“預編譯頭”,在右邊的“預編譯頭”下拉菜單中選擇“不使用預編譯頭文件”,點擊“確定”按鈕退出。
原因分析:編譯器一般都是以文件爲單位進行編譯,如果修改了工程中的一個文件,那麼將導致所有文件都要重新編譯,這樣的編譯將耗費很長時間。爲了提高編譯速度,將那些不常被修改,比較穩定,文件單獨包含到一個指定的頭文件中,然後生成一個預編譯頭文件 *.pch 。 VC++中默認的頭文件爲 stdAfx.h, 但光有頭文件無法編譯,所以還要用到StdAfx.cpp,StdAfx.cpp裏只包含一句有效代碼,這樣編譯時,通過編譯 stdAfx.cpp就把大部分系統頭文件編譯進來, Debug目錄下便會產生一個 存儲了預編譯信息的 *.pch 文件。如果 *.pch文件損壞或者不存在,就會出現“問題1”所示的無法打開預編譯頭文件的錯。
如需深究,可參考博客:無法打開包括文件:“Stdfx.h”
問題2:解決了問題1之後,又出現:errorMSB8011: 未能註冊輸出。請嘗試啓用“逐用戶重定向”,或者使用提升的權限從命令提示符處註冊該組件。
解決:項目-》屬性-》鏈接器-》逐用戶重定向--》設置爲 true (該方案網上常見,但仍“未能”根本解決問題)
分析: 由於win7權限問題,所以出現問題3,需要通過使用命令提示符來幫助註冊該組件。
問題3:無法啓動程序:“I:\VSProject\FirstCOM\Debug\FirstCOM.dll”。
解決:程序 --》 附件 --》 命令提示符,在”命令提示符“上點擊鼠標右鍵,選擇”以管理員身份運行“命令,這個時候將打開Dos命令窗口。
接下來輸入:regsvr32 “I:\VS Project\FirstCOM\Debug\FirstCOM.dll” (就是 regsvr32+.dll文件所在的完全路徑了,全路徑最好用引號括起來)
按Enter 鍵,就能夠註冊成功了。
下面簡單介紹如何調用COM組件。
1、在MFC中調用有一種很方便的方法,就是通過ClassWizard利用類型庫生成包裝類,不過有個前提就是com組件的接口必須是派生自IDispatch。
具體方法:
(1)VS2010新建一個MFC基於對話框程序,調出類嚮導,點擊“添加類”下拉菜單,選擇“類型庫中的MFC類”(From a type libarary)。
(2)選“註冊表”,然後在“可用類型庫”中定位到FirstCOMLib<1.0>,接下來會出來該庫中的所有接口,選擇你想生成的接口包裝類IFirstClass後點擊“完成”,嚮導會自動生成相應的.h文件,這樣你就可以在你的MFC工程中像使用普通類那樣使用COM組件了.
(3)代碼編寫:
首先引入頭文件 #include "CFirstClass.h"
爲對話框程序添加一個“測試”按鈕,添加按鈕單擊響應函數
- void CFirstCOMTestDlg::OnBnClickedButton1()
- {
- // TODO: 在此添加控件通知處理程序代碼
- CoInitialize(NULL);
- CFirstClass m_mymath;
- if (!m_mymath.CreateDispatch(_T("FirstCOM.math.1")))//創建COM對象:這裏的字符串一定要和註冊表中的ProgID一致!!!
- {
- MessageBox(_T("創建COM組件失敗:請檢查ProgID是否正確,組件是否已經註冊"));
- return;
- }
- else
- {
- long ret = m_mymath.Add(1,2);//調用COM接口
- CString strTemp;
- strTemp.Format(_T("%d"),ret);
- MessageBox(strTemp);
- }
- CoUninitialize();
- }
<span style="font-size:14px;">void CFirstCOMTestDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知處理程序代碼
CoInitialize(NULL);
CFirstClass m_mymath;
if (!m_mymath.CreateDispatch(_T("FirstCOM.math.1")))//創建COM對象:這裏的字符串一定要和註冊表中的ProgID一致!!!
{
MessageBox(_T("創建COM組件失敗:請檢查ProgID是否正確,組件是否已經註冊"));
return;
}
else
{
long ret = m_mymath.Add(1,2);//調用COM接口
CString strTemp;
strTemp.Format(_T("%d"),ret);
MessageBox(strTemp);
}
CoUninitialize();
}
</span>
關於m_mymath.CreateDispatch(_T("FirstCOM.math.1")) 中字符串"FirstCOM.math.1",其實跟我們上一章中定義類時ProgID有關,如果忘記,可以在FirstClass.rgs文件裏找,rgs是組件註冊的腳本文件,當你用 Regsvr32.exe註冊組件時,組件內部便是調用了這個文件。rgs文件是以資源的形式存於DLL內的。
- KCR
- {
- FirstCOM.math.1 = s 'FirstClass Class'
- {
- CLSID = s '{C56D80DE-DA4C-4731-81A6-48B8D0BDB2FD}'
- }
- FirstCOM.math = s 'FirstClass Class'
- {
- CurVer = s 'FirstCOM.math.1'
- }
<span style="font-size:14px;">KCR
{
FirstCOM.math.1 = s 'FirstClass Class'
{
CLSID = s '{C56D80DE-DA4C-4731-81A6-48B8D0BDB2FD}'
}
FirstCOM.math = s 'FirstClass Class'
{
CurVer = s 'FirstCOM.math.1'
}
</span>
其中 CurVer=s'FirstCOM.math.1' 中的 FirstCOM.math.1 就是我們需要的那個字符串。
4)編譯運行,點擊測試按鈕,結果如下:
2、在SDK中調用最簡單最常用的一種,用#import導入類型庫,利用VC提供的智能指針包裝類
VS2010創建Win32控制檯應用程序,編寫如下代碼:
其中頭文件atlcomcli.h中定義了智能指針CComPtr。