gSoap的初步学习——1

来源:互联网 发布:vb的picturebox 编辑:程序博客网 时间:2024/06/18 11:37

本文中使用的gSoap版本是2.8.17的,采用的编译器是VS2008。下面先简要介绍下gSoap的相关知识。

一、gSoap基础知识简介

2.1 wsdl2h
      wsdl2h的使用方法:
           wsdl2h -o 头文件名 WSDL文件名或URL   

      wsdl2h常用选项

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

2.2  soapcpp2

soapcpp2的使用方法:

<span style="font-weight: normal;"><span style="font-family:SimSun;font-size:18px;">soapcpp2 头文件.h</span></span>
<span style="font-weight: normal;"><span style="font-family:SimSun;font-size:18px;">soapcpp2 ayandy.h</span></span>

将生成下面这些文件

  • soapStub.h    // soap的存根文件,定义了ayandy.h里对应的远程调用模型
  • soapC.c soapH.h // soap的序列和反序列代码,它已经包含了soapStub.h,服务器端与客户端都要包含它
  • soapClient.c soapClientLib.c // 客户端代码,soapClientLib.c文件则只是简单地包含soapClient.c和soapC.c
  • soapServer.c soapServerLib.c // 服务器端代码,soapServerLib.c文件则只是简单地包含soapServer.c和soapC.c
  • ServiceSoap.nsmap ServiceSoap12.nsmap // 名空间定义,服务器端与客户端都要包含它
  • soapServiceSoapProxy.h soapServiceSoap12Proxy.h // 客户端的C++简单包装(如果头文件是纯C代码,这两个文件就不会生成) 

    soapcpp2常用选项

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

三、gSoap使用实例

     本例中gSoap的目录D:\Language\gsoap\gsoap-2.8

3.1.Web Service服务端(C++)

[1]新建空的Win32控制台项目“MyFirstWS”。然后添加一个头文件“MyInterface.h”,输入你要暴露给WS客户端的方法声明,内容如下

int   ns__sqrt(double a, double &result);

[2]将D:\Language\gsoap\gsoap-2.8\gsoap\bin\win32中soapcpp2.exe复制到新建的win32项目目录中,在CMD中打开win32项目文件夹,运行命令“soapcpp2  -S  MyInterface.h”生成存根文件

将新生成的C++的源码文件加入到你的工程项目中,soapServerLib.cpp文件不用加。你需要修改自动生成的ns.wsdl文件(可用Notepad等方式打开该文件,在文件的末端可以找到侦听的端口),因为里面的Web Service侦听端口默认为80,但是我们一般不使用默认侦听端口。

[3]加入“D:\Language\gsoap\gsoap-2.8\gsoap”下的“stdsoap2.hstdsoap2.cppdom.cpp(可不要)”三个源文件到当前项目中。

[4]添加一个源文件,命名为:MyFirstWS.cpp,源文件内容如下

// MyFirstWS.cpp : Defines the entry point for the console application.//#include <tchar.h>#include "MyInterface.h"#include "ns.nsmap"//我的接口实现int ns__sqrt(struct soap *soap, double a, double &result)  {  if (a >= 0)  {  result = sqrt(a);  return SOAP_OK;  }  return soap_sender_fault(soap, "Square root of negative value", "I can only compute the square root of a non-negative value"); } //返回接口描述,否则在为C#代码添加服务引用时,找不到这个接口int http_get(struct soap   *soap) { std::string fileName = "ns.wsdl";if(strstr(soap->msgbuf,"clientaccesspolicy.xml")!=NULL){fileName = "clientaccesspolicy.xml";}//红色乃添加的代码FILE*fd = NULL;fd = fopen(fileName.c_str(), "rb"); //open WSDL file to copyif (!fd){return 404; //return HTTP not found error}soap->http_content = "text/xml";  //HTTP header with text /xml contentsoap_response(soap,SOAP_FILE);for(;;){size_t r = fread(soap->tmpbuf,1, sizeof(soap->tmpbuf), fd);if (!r){break;}if (soap_send_raw(soap, soap->tmpbuf, r)){break; //cannot send, but little we can do about that}}fclose(fd);soap_end_send(soap);return SOAP_OK; }int _tmain(int argc, _TCHAR* argv[]){int m, s; /* master and slave sockets *///初始化soap环境变量struct soap sqrt_soap;soap_init(&sqrt_soap);//添加,返回接口描述(WSDL)的功能,//否则其它语言在建立Web Service客户端的时候,无法自动生成代码sqrt_soap.fget = http_get;    //服务端侦听端口设为8080,注意ns.wsdl文件内容要做相应修改m = soap_bind(&sqrt_soap, NULL, 8080, 100);if (m < 0){soap_print_fault(&sqrt_soap, stderr);exit(-1);}fprintf(stderr, "Socket connection successful: master socket = %d\n", m);for ( ; ; ){ s = soap_accept(&sqrt_soap); if (s < 0){ soap_print_fault(&sqrt_soap, stderr);exit(-1);}fprintf(stderr, "Socket connection successful: slave socket = %d\n", s);soap_serve(&sqrt_soap);soap_end(&sqrt_soap);}return 0;}

3.2 WebService客户端(C++语言)

[1]新建C++Console工程,运行3.1中创建的WebService服务端(这步很重要)

[2]将gSoap中的wsdl2h.exe和soapcpp2.exe复制到新建工程目录中,根据http://localhost:8080/网址打印出的WSDL信息产生MyInterface.h头文件,在CMD中打开新建工程的目录文件夹,然后输入下面命令

wsdl2h  -o  MyInterface.h  http://localhost:8080/

[3]根据“MyInterface.h”头文件生成存根文件

soapcpp2  -i -C  -I D:\Language\gsoap\gsoap-2.8\gsoap\import MyInterface.h

-C”参数指定只生成客户端存根文件,默认服务端和客户端存根文件都生成。“-I”参数指定stlvector.h文件的搜索路径。“D:\Language\gsoap\gsoap-2.8\gsoap\import”是我gsoap  Toolkit的存放路径。在项目中添加新生成的源文件,soapClientLib.cpp文件不用添加。

[4]在项目中添加D:\Language\gsoap\gsoap-2.8\gsoap\目录下的stdsoap2.hstdsoap2.cppdom.cpp三个文件。

[5]修改项目默认的cpp文件,源码清单如下

// MyFirstWSClient.cpp : Defines the entry point for the console application.////服务端提供的功能可以查看下面的头文件内容//如果服务端的URL地址或侦听端口改变,需要修改下面这个头文件#include "soapServiceProxy.h"//下面这个头文件是必须的,否则stdsoap2.obj连接的时候会出错#include "Service.nsmap"#include <tchar.h>int _tmain(int argc, _TCHAR* argv[]){ServiceProxy srv;double dR;_ns2__sqrt         call;      //形参表_ns2__sqrtResponse response;  //返回调用结果call.a = 4.0;int nR = srv.sqrt(&call,&response);//调用sqrt函数if( nR == SOAP_OK){dR = response.result;printf("成功返回,sqrt(4)=%f\n",response.result);} else{printf("请检查网络连接!");}    while(1);return 0;}

0 0