zoukankan      html  css  js  c++  java
  • Gsoap使用心得

        最近用到vc mfc 调用c#写的wcf 发布的webservice 上传文件.服务器端接收object 类型的byte[]数组。

               我本来还以为vs2010中vc能象c#一样方便的使用web service(记得vs2005,vs2008的vc clr 可以直接增加引用),可是找了半天头大了!!

               网上找了下,大家都是用的gsoap,但是能查到的资料,都是接收简单数据的,于是效仿,对gsoap生成的代理类,和数据类型研读,问题解决了。

        1、 先了解一下Gsoap

              gSOAP一种跨平台的C和 C++软件开发工具包。生成C/C++的RPC代码,XML数据绑定,对SOAP Web服务和其他应用形成高效的具体架构解析器,它们都受益于一个XML接口。

         这个工具包提供了一个全面和透明的XML数据绑定解决方案,Autocoding节省大量开发时间来执行SOAP/XML Web服务中的C/C++。此外,使用XML数据绑定大大简化了XML自动映

         射。应用开发人员不再需要调整应用程序逻辑的具体库和XML为中心的数据,如 交涉DOM。

              我们可以使用gSOAP提供的工具直接根据wsdl文档,生成所需要的数据类型,并将底层实现完全封装,我们只需要简单的操作代理类,就可以很轻松的实现调用。

         2、  Gsoap优点

               夸平台。支持linux386(MAC OS X universal binaries),macosx(Linux i386 compatible),win32(Windows 386 compatible)等。

               稳定性:该软件已经成熟。自2001年以来经过几年的发展和试验。许多工业项目和产品都在使用该软件。

               开源:可选择自由和商业许可。

               C和C++的支持:支持纯粹的ANSI C和混合的C/C++应用开发。

               行业标准协议: SOAP 1.1/1.2 WSDL 1.1,v2和UDDI 。支持XML架构原始XSD结构类型等等。

          3、 不废话了直接按地址下载:

               下载地址:http://sourceforge.net/projects/gsoap2

               解压gsoap_2.8.14.zip

               在目录gsoap-2.8\gsoap\win32下,存在2个exe 文件:

               soapcpp2.exe  该工具转换WSDL和XSD文件到带有注释的C/C++定义文件。

                Wsdl2h.exe  该工具从带有注释的C/C/++定义文件生成RPC代码和XML序列化

               在目录gsoap-2.8\gsoap\doc下帮助文裆。

               首先用C# wcf写个测试用的服务端代码(wcf 3.5):

               发布的方法如下:

              

    复制代码
    public int testAdd(int intA, int intB)
    { 
          Return  intA+intB;
    }
    
    public string upDateFile(string  ilename, object objfile)
    { 
          Byte[] mt=(byte) objfile;
          …………………
    }
    复制代码

               然后启动,发布成web service .地址为http://127.0.0.1:2002/myBehavior?wsdl

              其次:用Vc进行调用完成客户端功能,实现步骤如下:

              开始-运行-cmd进入dos模式,进入gsoap-2.8\gsoap\win32目录。

              1、  根据wsdl文档生成头文件.

              Wsdl2h  -1 –t  ..\..\typemap.dat  -s -0  test.h   http://127.0.0.1:2002/myBehavior?wsdl

              参数只写了几个常用的,其他的可以查询帮助。

    -t file

    use type map file instead of the default file typemap.dat

    -s

    don’t generate STL code (no std::string and no std::vector)

    -o file

    output to file

     

             2、 soapcpp2.exe -C -L -j -d "C:\test" -w -x "test.h" 

             注意:1、 如果不使用–t参数的话,默认soapcpp2相同的目录。

                      2、我所使用的服务端是wcf3.5支持的是soap 1.0 所以使用参数 -1, 如果不设置此参数,将默认soap 1.2版本。

    -C

    Generate client-side code only

    -L

    Do not generate soapClientLib/soapServerLib

    -j

    Generate C++ service proxies and objects that can share a soap struct

    -d <path>

    Save sources in directory specified by <path>

    -w

    Do not generate WSDL and schema files

    -x

    Do not generate sample XML message files

    -1

    Generate SOAP 1.1 bindings

    -2

    Generate SOAP 1.2 bindings

    将如下文件列表

     

            BasicHttpBinding_USCOREIDataService.nsmap

            soapBasicHttpBinding_USCOREIDataServiceProxy.cpp

            soapBasicHttpBinding_USCOREIDataServiceProxy.h

            soapC.cpp

            soapH.h

            soapStub.h

            将生成文件及stdsoap2.c,soap12.h,stdsoap2.cpp,加入到工程,

           1、右键选择soapC.cpp、soapBasicHttpBinding_USCOREIDataServiceProxy.cpp、stdsoap2.cpp,点击"属性",如下图所

     

             2、选择 预编译-》预编译头设置为 不使用预编译头文件。

     

           在使用代码中加入头文件:

          #include "soap\ soapBasicHttpBinding_USCOREIDataServiceProxy.cpp "
          #include 
    "soap\ BasicHttpBinding_USCOREIDataService.nsmap"


          代码实现部分如下:

    复制代码
    struct soap clientSOAP;
    soap_init(&clientSOAP);
    
    
    //简单的传值没有什么疑问
    struct _ns1__ testAdd testAdd;
    struct _ns1__ testAdd Response testAddResponse;
    
    xsd__int intA;
    intA. __item=5;
    xsd__int intB;
    intB. __item=3;
    
    testAdd. intA = intA;
    testAdd. intB = intB;
    BasicHttpBinding_USCOREIDataServiceProxy test;
    
     
    
    test.soap_endpoint=”http://127.0.0.1:2002/myBehavior?wsdl”;
    
    int soapResult= test. testAdd (&testAdd,& testAddResponse);
    if(soapResult==SOAP_OK)
    {
           Int result= testAddResponse. testAddResult;
    }
    else
    {
           int m=GetLastError();
            ………
    }
    /*
    web service 定义的object类型数据,在wsdl xml 中被定义为xsd:anyType,
    而对应代理类中的xsd__anyType,要确认参数实际内容,需要获得接口的帮助,确定传值。本实例测试传输的是byte数组,二进制。
    */
    
    struct _ns1__ upDateFile upDateFile;
    struct _ns1__ upDateFileResponse upDateFileResponse;
    
       
    
    //先将数据传给基础byte类型
    // vobjFile
    
    xsd__base64Binary  v ;
    v.__ptr=new BYTE[vobjFileSize];
    v.__size=vobjFileSize;
    memcpy(v.__ptr,vobjFile, vobjFileSize);
    v.soap=&clientSOAP;
    
    //将基础类型传给从,xsd__anytype派生来的byte
    
    xsd__base64Binary_ *v1 =new xsd__base64Binary_() ;
    v1->__item=v;
    upDateFile.objName=vFileName;
    
    //生成代理类的时候,xsd:anytype,对应生成 xsd__anytype
    upDateFile.objPgc=v1;
    BasicHttpBinding_USCOREIDataServiceProxy test;
    
    test.soap_endpoint=”http://127.0.0.1:2002/myBehavior?wsdl”;
    
    int soapResult= test.upDateFile(&upDateFile,& upDateFileResponse);
    if(soapResult==SOAP_OK)
    {
    
         char *result;
         result=new char[10];
         result= upDateFileResponse. 
         upDateFileResponseResult;
    
         delete result;
         if (atoi(result)==0)
         {
               ………
    
         }
    }
    else
    {
          int m=GetLastError();
           ………
    }
        
    delete v1;
    upfile.destroy();
    复制代码

    问题解决!!

     
     
    分类: C++
  • 相关阅读:
    Dropdown 下拉菜单
    Breadcrumb 面包屑
    Tabs 标签页
    NavMenu 导航菜单
    Notification 通知
    MessageBox 弹框
    Message 消息提示
    Loading 加载
    Alert 警告
    Badge 标记
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2996992.html
Copyright © 2011-2022 走看看