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++
  • 相关阅读:
    《C# to IL》第一章 IL入门
    multiple users to one ec2 instance setup
    Route53 health check与 Cloudwatch alarm 没法绑定
    rsync aws ec2 pem
    通过jvm 查看死锁
    wait, notify 使用清晰讲解
    for aws associate exam
    docker 容器不能联网
    本地运行aws lambda credential 配置 (missing credential config error)
    Cannot connect to the Docker daemon. Is 'docker daemon' running on this host?
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2996992.html
Copyright © 2011-2022 走看看