Fork me on GitHub
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++
posted on 2013-04-02 23:02  HackerVirus  阅读(371)  评论(0编辑  收藏  举报