C++ ATL Server 创建 XML Web Service

作为一名C++程序员,如果厌倦了DCOM和RPC的繁琐实现和调试,可能想要寻找一种新的方式来管理代码。如果不想错过接触XML Web Service的机会,可能会考虑使用.NET(C#)来创建一个。但是,如果追求更高的性能,可能会选择ATL Server Web Service。本文基于MSDN的教程《使用ATL Server创建XML Web服务》,演示了如何使用C++和ATL Server创建一个将华氏温度转换为摄氏温度的XML Web服务。已经增强了ATL Server Web Service函数的功能,使其能够转换华氏温度和摄氏温度,并使用MFC客户端代替控制台应用程序来使用这个Web服务。代码是未管理的C++,而不是托管的。

将完成以下活动:

在本教程的过程中,将完成以下活动:

  • 创建一个名为TempConvert的XML Web服务项目。
  • 实现XML Web服务。
  • 部署XML Web服务。
  • 创建一个MFC应用程序来调用XML Web服务。

创建XML Web服务项目

首先,应该创建一个空白解决方案TempConvert。然后,可以使用向导添加一个新的XML Web服务项目,名为TempConvert到这个解决方案中。

实现XML Web服务

ATL Server使用ISAPI扩展DLL来调用Web服务应用程序DLL中定义的函数处理程序,以响应XML Web服务请求。

1. 在接口ITempConvertService中,用以下代码替换TempConvert.h中的示例helloWorld方法:

__interface ITempConvertService { // 声明一个Web服务方法及其输入参数和输出参数 [id(1)] HRESULT ConTempFah2Cel([in] double dFahrenheit, [out, retval] double* pdCelsius); [id(2)] HRESULT ConTempCel2Fah([in] double dCelsius, [out, retval] double* pdFahrenheit); };

2. CTempConvertService类提供了XML Web服务的实现。将代码添加到TempConvert.h文件中。

class CTempConvertService : public ITempConvertService { public: [soap_method] HRESULT ConTempFah2Cel(double dFahrenheit, double* pdCelsius) { if (!pdCelsius) return E_INVALIDARG; *pdCelsius = ((dFahrenheit - 32) * 5) / 9; return S_OK; } [soap_method] HRESULT ConTempCel2Fah(double dCelsius, double* pdFahrenheit) { if (!pdFahrenheit) return E_INVALIDARG; *pdFahrenheit = dCelsius * 9 / 5 + 32; return S_OK; } };

部署XML Web服务

如果一切顺利,编译解决方案并将其部署到机器上,这里是本地站点localhost,可以在IE中查看:http://localhost/TempConvert/TempConvert.dll?Handler=GenTempConvertWSDL。它只显示XML。将使用以下MFC客户端调用XML Web服务。

创建MFC应用程序以调用XML Web服务

1. 创建一个基于对话框的MFC应用程序TempConvertClient。

2. 使用URL添加Web引用:http://localhost/TempConvert/TempConvert.dll?Handler=GenTempConvertWSDL,一个可用的替代URL是:http://ws.bomege.com/bin/TempConvert.dll?Handler=GenTempConvertWSDL(源代码应用此URL),并将其重命名为TempConvert。

3. 向对话框添加新控件。

4. 打开文件TempConvertClientDlg.h,添加变量和方法到CTempConvertClientDlg类中:

class CTempConvertClientDlg : public CDialog { public: CTempConvertClientDlg(CWnd* pParent = NULL); enum { IDD = IDD_TEMPCONVERTCLIENT_DIALOG }; protected: virtual void DoDataExchange(CDataExchange* pDX); afx_msg void OnBnClickedC2F(); afx_msg void OnBnClickedF2C(); protected: HICON m_hIcon; double m_dTempF; double m_dTempC; protected: virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); afx_msg void OnConvert(); DECLARE_MESSAGE_MAP() };

5. 在文件TempConvertClientDlg.cpp中,添加实现方法和转换按钮的事件处理程序:

void CTempConvertClientDlg::OnConvert() { UpdateData(TRUE); CoInitialize(NULL); HRESULT hr = S_OK; UINT m_iRadio = GetCheckedRadioButton(IDC_RADIOF2C, IDC_RADIOC2F); GetDlgItem(IDC_CONVERT)->EnableWindow(FALSE); CTempConvertService *pTempCon = new CTempConvertService; switch (m_iRadio) { case IDC_RADIOC2F: { double dFah; hr = pTempCon->ConTempCel2Fah(m_dTempC, &dFah); if (SUCCEEDED(hr)) { m_dTempF = dFah; GetDlgItem(IDC_CONVERT)->EnableWindow(); UpdateData(FALSE); } else { MessageBox(_T("Convert Service Failed!"), _T("Service Failed"), MB_OK | MB_ICONHAND); } } case IDC_RADIOF2C: { double dCel; hr = pTempCon->ConTempFah2Cel(m_dTempF, &dCel); if (SUCCEEDED(hr)) { m_dTempC = dCel; GetDlgItem(IDC_CONVERT)->EnableWindow(); UpdateData(FALSE); } else { MessageBox(_T("Convert Service Failed!"), _T("Service Failed"), MB_OK | MB_ICONHAND); } } } delete pTempCon; CoUninitialize(); }

6. 当点击单选控件时,将向名为Convert的按钮发送BM_CLICK消息:

void CTempConvertClientDlg::OnBnClickedC2F() { GetDlgItem(IDC_CONVERT)->SendMessage(BM_CLICK, 0, 0); } void CTempConvertClientDlg::OnBnClickedF2C() { GetDlgItem(IDC_CONVERT)->SendMessage(BM_CLICK, 0, 0); }

故障排除

1. Web服务项目构建成功但无法运行?需要在IIS配置中向ISAPI DLL添加一个"dll"解析,它将处理应用程序dll。

2. 源代码使用的是VS.NETC++2005,如果使用的是早期版本的VS C++,只需创建一个新的空白解决方案项目并添加*.cpp, *.h等项目即可。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485