gSOAP编译和学习



目录(?)[+]

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

一.安装

Linux环境:ubuntu,root用户 
1.下载gSOAP 
gSOAP官网:http://www.cs.fsu.edu/~engelen/soap.html 
2.安装编译工具:

apt-get install build-essential
//为了成功编译gSOAP,您需要安装GTK+的开发文件和GLib库(libraries)
apt-get install libgtk2.0-dev libglib2.0-dev
//安装Checkinstall以便管理您系统中直接由源代码编译安装的软件
apt-get install checkinstall
//yacc(Yet Another Compiler Compiler),是Unix/Linux上一个用来生成编译器的编译器(编译器代码生成器)
apt-get install flex bison
//安装OpenSSL通常的库文件,首先使用以下命令来确定在Ubuntu系统中可获得的库文件的应用版本:
sudo apt-cache search libssl | grep SSL
sudo apt-get install libssl-dev
sudo apt-get install openssl
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

3.编译安装gSOAP 
./configure –prefix=/usr/local/gSOAP(指定安装路径) 
make 
make install 
______________________________Install over______________ 
安装成功示图

二.学习

gSOAP两大工具

1.wsdl2h的作用是根据WSDL生成C/C++风格的头文件

wsdl2h -o 头文件名 WSDL文件名或URL
   
   
  • 1
  • 1

wsdl2h常用选项

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

type map文件用于指定SOAP/XML中的类型与C/C++之间的转换规则,比如在wsmap.dat里写

xsd__string = | std::wstring | wchar_t*
   
   
  • 1
  • 1

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

2.从头文件生成存根(stub)和框架(Skeleton)源文件,soapcpp2的作用是根据头文件自动生成调用远程 SOAP服务的客户端代码(称为存根:Stub)和提供SOAP服务的框架代码(称为框架:Skeleton),另外它也能从头文件生成WSDL文件 
编写SOAP程序除了头文件是不够的,还要有连接、通信、XML解析、序列/反序列化等工作。gSOAP提供的socapcpp2就是用于从头文件中生成这些代码的

soapcpp2 头文件    //用法
   
   
  • 1
  • 1

生成的文件描述:

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代码,这两个文件就不会生成)
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

综上所述

如果编写服务器端,项目里应该加入soapServerLib.c,代码里包含头文件soapH.h
如果编写客户端,项目里应该加入soapClientLib.c,代码里包含头文件SoapH.h(或xxxxProxy.h)
当然,还要加入gsoap库里的stdsoap2.cpp文件(如果是写C代码,则加入stdsoap2.c)

如果看到soapcpp2提示:”Critical error: #import: Cannot open file “stlvector.h” for reading.“, 那是因为我们的头文件使用了STL(wsdl2h 没用-s选项),这时要使用-I选项指定gSOAP的 import文件路径,这个路径是”$gsoap\gsoap\import”:

soapcpp2 -j -SL -I/path/to/gsoap/import calc.h  //例子
   
   
  • 1
  • 1

soapcpp2常用选项

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

Example gSOAP client(c++)

wsdl2h -o calc.h http://www.genivia.com/calc.wsdl   //生成calc.h
soapcpp2 -j -CL -I/usr/local/gSOAP/share/gsoap/import calc.h    // /usr/local/gSOAP/share/gsoap/import==你的路径,如下图:
   
   
  • 1
  • 2
  • 1
  • 2

这里写图片描述

新建一个客户端程序调用计算器service:calcclient.cpp

//calcclient.cpp
#include "calc.nsmap"      // XML namespace mapping table (only needed once at the global level)
#include "soapcalcProxy.h" // the proxy class, also #includes "soapH.h" and "soapStub.h"

int main()
{
  calcProxy calc;
  double sum;
  if (calc.add(1.23, 4.56, sum) == SOAP_OK)
    std::cout << "Sum = " << sum << std::endl;
  else
    calc.soap_stream_fault(std::cerr);
  calc.destroy(); // same as: soap_destroy(calc.soap); soap_end(calc.soap);
}
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
//若提示没有stdsoap2.cpp文件,则复制该文件到当前路径下即可
g++ -o calcclient calcclient.cpp soapC.cpp soapcalcProxy.cpp stdsoap2.cpp
./calcclient
Sum = 5.79
   
   
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

Example gSOAP server(c++)

wsdl2h -o calc.h http://www.genivia.com/calc.wsdl   //生成calc.h
soapcpp2 -j -SL -I/usr/local/gSOAP/share/gsoap/import calc.h
   
   
  • 1
  • 2
  • 1
  • 2

新建一个服务端程序:calcserver.cpp

//calcserver.cpp
//g++ -o calcserver calcserver.cpp soapC.cpp soapcalcService.cpp stdsoap2.cpp

#include "calc.nsmap"        // XML namespace mapping table (only needed once at the global level)
#include "soapcalcService.h" // the service class, also #includes "soapH.h" and "soapStub.h"

int main()
{
  calcService calc(SOAP_XML_INDENT);
  calc.soap->send_timeout = 5; // send timeout is 5s
  calc.soap->recv_timeout = 5; // receive timeout is 5s
  while (calc.run(8090) != SOAP_OK)
    calc.soap_stream_fault(std::cerr);
  calc.destroy(); // same as: soap_destroy(calc.soap); soap_end(calc.soap);
}
int calcService::add(double a, double b, double &result)
{
  result = a + b;
  return SOAP_OK;
}
int calcService::sub(double a, double b, double &result)
{
  result = a - b;
  return SOAP_OK;
}
int calcService::mul(double a, double b, double &result)
{
  result = a * b;
  return SOAP_OK;
}
int calcService::div(double a, double b, double &result)
{
  if (b == 0.0)
  {
    char *msg = (char*)soap_malloc(this->soap, 1024);
    snprintf(msg, 1024, "Trying to divide %f by zero", a);
    return this->soap_senderfault(msg, NULL);
  }
  result = a / b;
  return SOAP_OK;
}
int calcService::pow(double a, double b, double &result)
{
  result = ::pow(a, b);
  // soap_errno is like errno, but compatible with Win32
  if (soap_errno == EDOM)
  {
    char *msg = (char*)soap_malloc(this->soap, 1024);
    snprintf(msg, 1024, "<error xmlns=\"http://tempuri.org/\">Can't take power of %f to %f</error>", a, b);
    return this->soap_senderfault("Power function domain error", msg);
  }
  return SOAP_OK;
}
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

链接:

项目主页: http://gsoap2.sourceforge.net
下载地址: http://sourceforge.net/projects/gsoap2/files/latest/download
项目托管地址:
    SvnSyncRepository: https://gsoap2.svn.sourceforge.net/svnroot/gsoap2
其他链接:
    Documentation: http://www.cs.fsu.edu/~engelen/soapdoc2.html
    Developer Center: http://www.genivia.com/dev.html
    gSOAP users mailing list: http://tech.groups.yahoo.com/group/gsoap/
    FAQ: http://www.cs.fsu.edu/~engelen/soapfaq.html
    百度百科地址: http://baike.baidu.com/view/2788733.htm
    Github项目地址: https://github.com/stoneyrh/gSOAP

目录(?)[+]

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

一.安装

Linux环境:ubuntu,root用户 
1.下载gSOAP 
gSOAP官网:http://www.cs.fsu.edu/~engelen/soap.html 
2.安装编译工具:

apt-get install build-essential
//为了成功编译gSOAP,您需要安装GTK+的开发文件和GLib库(libraries)
apt-get install libgtk2.0-dev libglib2.0-dev
//安装Checkinstall以便管理您系统中直接由源代码编译安装的软件
apt-get install checkinstall
//yacc(Yet Another Compiler Compiler),是Unix/Linux上一个用来生成编译器的编译器(编译器代码生成器)
apt-get install flex bison
//安装OpenSSL通常的库文件,首先使用以下命令来确定在Ubuntu系统中可获得的库文件的应用版本:
sudo apt-cache search libssl | grep SSL
sudo apt-get install libssl-dev
sudo apt-get install openssl
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

3.编译安装gSOAP 
./configure –prefix=/usr/local/gSOAP(指定安装路径) 
make 
make install 
______________________________Install over______________ 
安装成功示图

二.学习

gSOAP两大工具

1.wsdl2h的作用是根据WSDL生成C/C++风格的头文件

wsdl2h -o 头文件名 WSDL文件名或URL
    
    
  • 1
  • 1

wsdl2h常用选项

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

type map文件用于指定SOAP/XML中的类型与C/C++之间的转换规则,比如在wsmap.dat里写

xsd__string = | std::wstring | wchar_t*
    
    
  • 1
  • 1

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

2.从头文件生成存根(stub)和框架(Skeleton)源文件,soapcpp2的作用是根据头文件自动生成调用远程 SOAP服务的客户端代码(称为存根:Stub)和提供SOAP服务的框架代码(称为框架:Skeleton),另外它也能从头文件生成WSDL文件 
编写SOAP程序除了头文件是不够的,还要有连接、通信、XML解析、序列/反序列化等工作。gSOAP提供的socapcpp2就是用于从头文件中生成这些代码的

soapcpp2 头文件    //用法
    
    
  • 1
  • 1

生成的文件描述:

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代码,这两个文件就不会生成)
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

综上所述

如果编写服务器端,项目里应该加入soapServerLib.c,代码里包含头文件soapH.h
如果编写客户端,项目里应该加入soapClientLib.c,代码里包含头文件SoapH.h(或xxxxProxy.h)
当然,还要加入gsoap库里的stdsoap2.cpp文件(如果是写C代码,则加入stdsoap2.c)

如果看到soapcpp2提示:”Critical error: #import: Cannot open file “stlvector.h” for reading.“, 那是因为我们的头文件使用了STL(wsdl2h 没用-s选项),这时要使用-I选项指定gSOAP的 import文件路径,这个路径是”$gsoap\gsoap\import”:

soapcpp2 -j -SL -I/path/to/gsoap/import calc.h  //例子
    
    
  • 1
  • 1

soapcpp2常用选项

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

Example gSOAP client(c++)

wsdl2h -o calc.h http://www.genivia.com/calc.wsdl   //生成calc.h
soapcpp2 -j -CL -I/usr/local/gSOAP/share/gsoap/import calc.h    // /usr/local/gSOAP/share/gsoap/import==你的路径,如下图:
    
    
  • 1
  • 2
  • 1
  • 2

这里写图片描述

新建一个客户端程序调用计算器service:calcclient.cpp

//calcclient.cpp
#include "calc.nsmap"      // XML namespace mapping table (only needed once at the global level)
#include "soapcalcProxy.h" // the proxy class, also #includes "soapH.h" and "soapStub.h"

int main()
{
  calcProxy calc;
  double sum;
  if (calc.add(1.23, 4.56, sum) == SOAP_OK)
    std::cout << "Sum = " << sum << std::endl;
  else
    calc.soap_stream_fault(std::cerr);
  calc.destroy(); // same as: soap_destroy(calc.soap); soap_end(calc.soap);
}
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
//若提示没有stdsoap2.cpp文件,则复制该文件到当前路径下即可
g++ -o calcclient calcclient.cpp soapC.cpp soapcalcProxy.cpp stdsoap2.cpp
./calcclient
Sum = 5.79
    
    
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

Example gSOAP server(c++)

wsdl2h -o calc.h http://www.genivia.com/calc.wsdl   //生成calc.h
soapcpp2 -j -SL -I/usr/local/gSOAP/share/gsoap/import calc.h
    
    
  • 1
  • 2
  • 1
  • 2

新建一个服务端程序:calcserver.cpp

//calcserver.cpp
//g++ -o calcserver calcserver.cpp soapC.cpp soapcalcService.cpp stdsoap2.cpp

#include "calc.nsmap"        // XML namespace mapping table (only needed once at the global level)
#include "soapcalcService.h" // the service class, also #includes "soapH.h" and "soapStub.h"

int main()
{
  calcService calc(SOAP_XML_INDENT);
  calc.soap->send_timeout = 5; // send timeout is 5s
  calc.soap->recv_timeout = 5; // receive timeout is 5s
  while (calc.run(8090) != SOAP_OK)
    calc.soap_stream_fault(std::cerr);
  calc.destroy(); // same as: soap_destroy(calc.soap); soap_end(calc.soap);
}
int calcService::add(double a, double b, double &result)
{
  result = a + b;
  return SOAP_OK;
}
int calcService::sub(double a, double b, double &result)
{
  result = a - b;
  return SOAP_OK;
}
int calcService::mul(double a, double b, double &result)
{
  result = a * b;
  return SOAP_OK;
}
int calcService::div(double a, double b, double &result)
{
  if (b == 0.0)
  {
    char *msg = (char*)soap_malloc(this->soap, 1024);
    snprintf(msg, 1024, "Trying to divide %f by zero", a);
    return this->soap_senderfault(msg, NULL);
  }
  result = a / b;
  return SOAP_OK;
}
int calcService::pow(double a, double b, double &result)
{
  result = ::pow(a, b);
  // soap_errno is like errno, but compatible with Win32
  if (soap_errno == EDOM)
  {
    char *msg = (char*)soap_malloc(this->soap, 1024);
    snprintf(msg, 1024, "<error xmlns=\"http://tempuri.org/\">Can't take power of %f to %f</error>", a, b);
    return this->soap_senderfault("Power function domain error", msg);
  }
  return SOAP_OK;
}
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

链接:

项目主页: http://gsoap2.sourceforge.net
下载地址: http://sourceforge.net/projects/gsoap2/files/latest/download
项目托管地址:
    SvnSyncRepository: https://gsoap2.svn.sourceforge.net/svnroot/gsoap2
其他链接:
    Documentation: http://www.cs.fsu.edu/~engelen/soapdoc2.html
    Developer Center: http://www.genivia.com/dev.html
    gSOAP users mailing list: http://tech.groups.yahoo.com/group/gsoap/
    FAQ: http://www.cs.fsu.edu/~engelen/soapfaq.html
    百度百科地址: http://baike.baidu.com/view/2788733.htm
    Github项目地址: https://github.com/stoneyrh/gSOAP
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值