zoukankan      html  css  js  c++  java
  • C++访问WebService gSoap方式

    一、             gSOAP访问WebService

    1.      下载gSOAP

    gSOAP 2.7.17 版下载地址http://sourceforge.net/projects/gsoap2/)

    2.      安装gSOAP

    解压下载的gsoap_2.7.17.zip,假设该路径为F:WebServicegsoap-2.7

    3.      通过WSDL生成C++头文件

    3.1、通过WSDL生成访问接口

        在 F:WebServicegsoap-2.7gsoapinwin32目录下建一个空的头文件WebService.h;再建立一个字符转换规则文件wsmap.dat,文件内容为xsd__string = | std::wstring | wchar_t*

    那么SOAP/XML中的string将转换成std::wstrin或wchar_t*,这样能更好地支持中文。

       启动cmd,进入到F:WebServicegsoap-2.7gsoapinwin32目录,调用wsdl2h.exe生成头文件接口定义,命令为:

    wsdl2h -o WebService.h -n WS -t wsmap.dat http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx?WSDL

                           

    • -o 文件名,指定输出头文件
    • -n 名空间前缀 代替默认的ns
    • -c 产生纯C代码,否则是C++代码
    • -s 不要使用STL代码
    • -t 文件名,指定type map文件,默认为typemap.dat
    • -e 禁止为enum成员加上名空间前缀

    3.2、解析WebService.h,生成存根程序

       在命令行输入soapcpp2 -C WebService.h -I F:WebServicegsoap-2.7gsoapimport

    最后提示成功,在F:WebServicegsoap-2.7gsoapinwin32目录中生成系列文件如下:

     

    • -C 仅生成客户端代码
    • -S 仅生成服务器端代码
    • -L 不要产生soapClientLib.c和soapServerLib.c文件
    • -c 产生纯C代码,否则是C++代码(与头文件有关)
    • -I 指定import路径(此项是必要的,因前面为指定-s)
    • -x 不要产生XML示例文件
    • -i生成C++包装,客户端为xxxxProxy.h(.cpp),服务器端为xxxxService.h(.cpp)。

     

    4.      建立工程

    4.1、头文件

    将生成的soapC.cpp、soapClient.cpp、soapH.h、soapStub.h、soapWeatherWSSoapProxy.h、WeatherWSSoap.nsmap、stdsoap2.h和stdsoap2.cpp文件加入到工程

    4.2、命名空间

    在工程的头文件中加入#include “WeatherWSSoap.nsmap”,否则会有命名空间编译出错的问题

    4.3、代码示例

    #include <iostream>

    #include <string>

     

    // 名称空间映射表

    #include "WeatherWSSoap.nsmap"

    #include "soapWeatherWSSoapProxy.h"

     

    using namespace std;

     

    main函数:

    // // 代理类对象

      WeatherWSSoap weatherwebservice;

     

      // 获取近5天天气情况及城市信息

      _ns1__getWeather cityName;

      _ns1__getWeatherResponse weatherResponse;

     

      cityName.theCityCode = L"北京";

     

      int result = weatherwebservice.__ns2__getWeather(&cityName, &weatherResponse);

     

      if(SOAP_OK == result)

      {

             vector<wstring> weatherString = weatherResponse.getWeatherResult->string;

     

             vector<wstring>::iterator itr;

             vector<wstring>::iterator itr_end;

     

             cout<<"近5天天气情况及城市信息:"<<endl;

     

             for(itr = weatherString.begin(),itr_end = weatherString.end(); itr!=itr_end; ++itr)

             {

                    wcout<<*itr<<endl;

             }

             cout<<endl;

      }

     

     第二种方式:

    在Visual Studio 2008以及以后版本中,微软停止了非托管C++的直接WebService引用。不过ATL Server代码已经托管到开源网站上,我们可以找到ATL Server的源代码,编译出Sproxy.exe,这个工具可以根据wsdl文件来生成非托管的代理类。这个代理类还需要配合一些头文件才能一起使用,这个相关的头文件都包含在ATL Server 的源代码内。

    1.第一步需要使用sproxy.exe工具来生成代理类。在vs2008以前的版本,比如vs2005,本身就带有这个命令,但在vs2008版,已经把它给去除了。需要去http://atlserver.codeplex.com/下载ATL_Server源代码并编译产生sproxy.exe工具。

    1.1先把下载好的文件ATL_Server_Source_and_Headers_9_0_70425_Alpha.rar解压出来,然后进入文件夹把include内的文件全部拷贝到vs2008的默认包含文件夹内,如我的路径:“D:ProgramFilesMicrosoft Visual Studio 9.0VCinclude”,拷贝之前最好先把原来的include文件夹备份一下。

    1.2之后用进入“ATL_Server_Source_and_Headers_9_0_70425_AlphasourceSProxy”,用vs2008打开“sproxy.sln”文件,并在vs2008提示下进行版本转换。

    1.3编译运行,生成sproxy.exe文件。

    2.为了测试webservice服务,在网上找了一个提供webservice的网站:http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx它提供天气预报服务。它的WSDL文件在这个:http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx?WSDL,这是一个xml文件,把这个文件保存为本地文件,名字叫WeatherWS.wsdl。为了方便,假定这个文件和sproxy.exe放在同一个目录下,执行命令

    sproxy.exe /wsdl WeatherWS.wsdl

    sproxy.exe /wsdl http://网址

    就会在同目录下生成WeatherWS.h文件。

    3. 打开vs2008,建立一个MFC项目WebService,在WebServiceDlg.cpp文件中添加

    #include "WeatherWS.h"

    using namespace WeatherWS;

    在按钮点击事件中加入下面的测试代码:

    void CWebServiceDlg::OnBnClickedButton1()

    {

           // TODO: 在此添加控件通知处理程序代码

           CoInitialize(NULL);

           HRESULT hr = S_OK;

           CWeatherWST<CSoapSocketClientT<>>* m_srv = new CWeatherWST<CSoapSocketClientT<>>;

           CComBSTR cityCode =""; //参数为空默认返回上海的天气情况 

           CComBSTR userId ="";

           CComBSTR * bstrOut;

           int size;

           hr =m_srv->getWeather(cityCode, userId, (BSTR * *)&bstrOut, &size);

           if(FAILED(hr))

           {

                  MessageBox(L"调用失败");

           }

           else

           {

                  MessageBox(L"调用成功");

           }

           if (m_srv != NULL)

                  delete m_srv;

           CoUninitialize();

    }

    以上资料整理来自网络,感谢原作者。

  • 相关阅读:
    .net Application的目录
    (转载).NET中RabbitMQ的使用
    (转载)RabbitMQ消息队列应用
    说说JSON和JSONP
    SQL Server中的事务与锁
    StackExchange.Redis Client(转载)
    正则语法的查询,这是纯转载的,为了方便查询
    Regex的性能问题
    解决json日期格式问题的办法
    BenchmarkDotNet(性能测试)
  • 原文地址:https://www.cnblogs.com/dengpeng1004/p/6165751.html
Copyright © 2011-2022 走看看