VC++ : VS2008 使用ATL开发COM组件
新建ATL Project,工程名命名为MyAtlCom;
出现工程 向导,一路“Next”;
Add class,点击添加 ATL Simple Object , 类名CStatistic, 接口IStatistic,“Next”到底;
打开类视图,可以看到ATLCOM下新增了CStatistic类和IStatistic接口;
在ISample上右键,Add->Add Method (或Add Property...)来丰富接口了,然后在CStatistic内实现相应的的方法(属性)即可。
增加一个Add方法:
STDMETHOD(Add)(LONG nNum1, LONG nNUm2, LONG* nRet); STDMETHODIMP CStatistic::Add(LONG nNum1, LONG nNUm2, LONG* nRet) { // TODO: Add your implementation code here *nRet = nNum1 + nNUm2; return S_OK; }
编译运行,生成MyAtlCom.dll,并注册到Windows中去。
下面,测试上述生成的COM组件MyAtlCom.dll
新建一个Win32控制台应用程序,取名MyAtlComTest
#include "stdafx.h" #include<iostream> using namespace std; #include "../MyAtlCom/MyAtlCom_i.h" #include "../MyAtlCom/MyAtlCom_i.c" int _tmain(int argc, _TCHAR* argv[]) { IStatistic * pIStatisticATL = NULL; HRESULT hr = CoInitialize(NULL); //初始化COM //使用SUCCEEDED宏并检查我们是否能得到一个接口指针 if(SUCCEEDED(hr)) { hr = CoCreateInstance(CLSID_Statistic, NULL, CLSCTX_INPROC_SERVER, IID_IStatistic, (void **)&pIStatisticATL); //如果成功,则调用Add方法,否则显示相应的出错信息 if(SUCCEEDED(hr)) { LONG nReturnValue; pIStatisticATL->Add(8, 9, &nReturnValue); cout << "The Add result for 8 + 9 is " << nReturnValue << endl; pIStatisticATL->Release(); } else { cout << "CoCreateInstance Failed." << endl; } } CoUninitialize(); //释放COM return 0; }
结果:
或使用IDispath接口
#include "stdafx.h" #include <atlbase.h> #include <atlcom.h> #include <iostream> using namespace std; #include "../MyAtlCom/MyAtlCom_i.h" #include "../MyAtlCom/MyAtlCom_i.c" int _tmain(int argc, _TCHAR* argv[]) { CoInitializeEx(NULL, COINIT_MULTITHREADED); CComPtr<IStatistic> spCar; spCar.CoCreateInstance(CLSID_Statistic); // use IDispatch DISPID PropertyID[1] = {0}; BSTR PropName[1]; PropName[0] = SysAllocString(L"Add"); HRESULT hr = spCar->GetIDsOfNames(IID_NULL, PropName, 1, LOCALE_SYSTEM_DEFAULT, PropertyID); SysFreeString(PropName[0]); CComVariant avarParams[3]; avarParams[2].vt = VT_I4; avarParams[2] = 8; avarParams[1].vt = VT_I4; avarParams[1] = 9; LONG vTotal = 0; avarParams[0].vt = VT_I4 | VT_BYREF; avarParams[0] = &vTotal; DISPPARAMS params = { avarParams, NULL, // Dispatch identifiers of named arguments. 3, // Number of arguments. 0 }; // Number of named arguments. CComVariant Result; hr = spCar->Invoke(PropertyID[0], IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, &Result, NULL, NULL); cout << "The Add function result is " << (int)(*params.rgvarg->plVal) << endl; spCar.Release(); CoUninitialize();
cin.get();
return 0;
}
结果:
使用COleDispatchDriver封装类
#include "stdafx.h" #include <atlbase.h> #include <atlcom.h> #include <iostream> using namespace std; #include "../MyAtlCom/MyAtlCom_i.h" #include "../MyAtlCom/MyAtlCom_i.c" int _tmain(int argc, _TCHAR* argv[]) { CoInitialize(NULL); COleDispatchDriver disp; COleException *e = new COleException; try { // Create instance of MyAtlCom Control by using CLSID. if (disp.CreateDispatch(CLSID_Statistic, e)) { static BYTE params[] = VTS_I4 VTS_I4 VTS_I4; LONG nNum1 = 4; LONG nNum2 = 5; LONG nAdd = 0; disp.InvokeHelper(0x01, DISPATCH_METHOD, VT_EMPTY, NULL, params, nNum1, nNum2, &nAdd); if (nAdd == nNum1 + nNum2) AfxMessageBox(_T("InvokerHelper successed!")); else { CString cStr; cStr.Format(_T("InvokerHelper Failed! Error %d"), GetLastError()); AfxMessageBox(cStr); } } else throw e; } //Catch control-specific exceptions. catch (COleDispatchException * e) { CString cStr; if (!e->m_strSource.IsEmpty()) cStr = e->m_strSource + " - "; if (!e->m_strDescription.IsEmpty()) cStr += e->m_strDescription; else cStr += "unknown error"; AfxMessageBox(cStr, MB_OK, (e->m_strHelpFile.IsEmpty())? 0:e->m_dwHelpContext); e->Delete(); } e->Delete(); CoUninitialize(); cin.get(); return 0; }
本文源码下载:仅供学习参考
百度云:http://pan.baidu.com/s/1pL13D03 密码:88ix
希望大家能把自己的所学和他人一起分享,不要去鄙视别人索取时的贪婪,因为最应该被鄙视的是不肯分享时的吝啬。