Posted on 2010-08-02 17:43
roy 阅读(3380)
评论(6) 编辑 收藏 引用 所属分类:
C/C++
-
- 电信provisioning系统中,常常需要与远程服务器实时交换一些数据,以完成用户的请求。由于简单对象访问协议(Simple
Object Access Protocol, SOAP)的流行,许多涉及到第三方的应用,我们一般都比较乐意使用SOAP来开发。不过,由于可能涉及到公司的机密,本系列教程的开发实例尽量采用在网上已经公开的Web
Service资源。
-
- gSOAP是一套开源的C/C++软件工具包,使用它能够很方便地开发SOAP网页服务和基于XML的应用程序,就像JAVA里面的axis。
-
- 首先,我们需要从以下地址下载最新版本的gSOAP
2.7.17:
- https://sourceforge.net/projects/gsoap2/files/
-
- 其次,gSOAP依赖于Bison和Flex,编译gSOAP的时候会用到,如果没有,从这里下载:
- Bison:http://www.gnu.org/software/bison/
- Flex:http://flex.sourceforge.net/
-
- 关于这两个工具包的安装步骤可以参考最新的LFS手册:
- http://www.linuxfromscratch.org/lfs/view/6.4/chapter06/bison.html
- http://www.linuxfromscratch.org/lfs/view/6.4/chapter06/flex.html
-
- 如果不是root用户,没有安装权限的话,可以在configure的时候使用--prefix=/path/to/your/own/directory,指定安装路径。装好之后,修改用户目录的.profile文件,更改PATH和LD_LIBRARY_PATH环境变量,使得系统能够正确搜索到你安装后的可执行文件和库文件即可。
-
- 这两步准备工作完成后,我们就可以开始编译gSOAP。Linux下编译安装源代码包无非就是tar zxvf xxx,configure,make,make
install,由于我不是root用户,没有安装的权限,那么不执行make install也可以使用gSOAP开发程序,只不过使用的时候常常需要指定路径。
-
- 现在我们的目标是开发一个获取股票信息的客户端程序。服务端采用webxml开发的WSDL,其URL是:http://webservice.webxml.com.cn/WebServices/ChinaStockWebService.asmx?wsdl
-
- 首先,在gsoap-2.7/gsoap/wsdl/下创建一个stock目录
- -bash-3.2$ mkdir -p stock
-
- 改变当前路径为stock
- -bash-3.2$ cd stock
-
- 使用wsdl2h生成stock.h,如果希望生成纯C代码,需要加上-c参数,否则,将会生成C++代码
- -bash-3.2$ ../wsdl2h -c -o
stock.h
http://webservice.webxml.com.cn/WebServices/ChinaStockWebService.asmx?wsdl
-
- ** The gSOAP WSDL/Schema processor for C and
C++, wsdl2h release 1.2.17
- ** Copyright (C) 2000-2010 Robert van Engelen,
Genivia Inc.
- ** All Rights Reserved. This product is provided
"as is", without any warranty.
- ** The wsdl2h tool is released under one of the
following two licenses:
- ** GPL or the commercial license by Genivia Inc.
Use option -l for more info.
-
- Saving
stock.h
-
- Cannot
open file 'typemap.dat'
- Problem
reading type map file 'typemap.dat'.
- Using
internal type definitions for C instead.
-
-
- Connecting
to 'http://webservice.webxml.com.cn/WebServices/ChinaStockWebService.asmx?wsdl'
to retrieve WSDL/XSD...
- Connected,
receiving...
- Done
reading
'http://webservice.webxml.com.cn/WebServices/ChinaStockWebService.asmx?wsdl'
-
- To
complete the process, compile with:
- >
soapcpp2 stock.h
-
- 然后,使用soapcpp2生成客户端存根程序和相关的头文件、资源文件,由于我们只开发客户端程序,所以可以指定-C参数
- -bash-3.2$ ../../bin/linux386/soapcpp2
-C stock.h
-
- ** The gSOAP code generator for C and C++,
soapcpp2 release 2.7.17
- ** Copyright (C) 2000-2010, Robert van Engelen,
Genivia Inc.
- ** All Rights Reserved. This product is provided
"as is", without any warranty.
- ** The soapcpp2 tool is released under one of
the following three licenses:
- ** GPL, the gSOAP public license, or the
commercial license by Genivia Inc.
-
- Saving
soapStub.h annotated copy of the input declarations
- Saving
soapH.h interface declarations
- Saving
soapC.c XML serializers
- Saving
soapClient.c client calling stubs
- Saving
soapClientLib.c client stubs with serializers (use only for libs)
- Using
ns2 service name: ChinaStockWebServiceSoap
- Using
ns2 service style: document
- Using
ns2 service encoding: literal
- Using
ns2 service location:
http://webservice.webxml.com.cn/WebServices/ChinaStockWebService.asmx
- Using
ns2 schema namespace: http://WebXml.com.cn/ChinaStockWebServiceSoap
- Saving
ChinaStockWebServiceSoap.getStockImageByCode.req.xml sample SOAP/XML request
- Saving
ChinaStockWebServiceSoap.getStockImageByCode.res.xml sample SOAP/XML response
- Saving
ChinaStockWebServiceSoap.getStockImageByteByCode.req.xml sample SOAP/XML
request
- Saving
ChinaStockWebServiceSoap.getStockImageByteByCode.res.xml sample SOAP/XML
response
- Saving
ChinaStockWebServiceSoap.getStockImage_kByCode.req.xml sample SOAP/XML request
- Saving
ChinaStockWebServiceSoap.getStockImage_kByCode.res.xml sample SOAP/XML response
- Saving ChinaStockWebServiceSoap.getStockImage_kByteByCode.req.xml
sample SOAP/XML request
- Saving
ChinaStockWebServiceSoap.getStockImage_kByteByCode.res.xml sample SOAP/XML
response
- Saving
ChinaStockWebServiceSoap.getStockInfoByCode.req.xml sample SOAP/XML request
- Saving
ChinaStockWebServiceSoap.getStockInfoByCode.res.xml sample SOAP/XML response
- Saving
ChinaStockWebServiceSoap.nsmap namespace mapping table
- Using
ns3 service name: ChinaStockWebServiceSoap12
- Using
ns3 service style: document
- Using
ns3 service encoding: literal
- Using
ns3 service location:
http://webservice.webxml.com.cn/WebServices/ChinaStockWebService.asmx
- Using
ns3 schema namespace: http://WebXml.com.cn/ChinaStockWebServiceSoap12
- Saving
ChinaStockWebServiceSoap12.getStockImageByCode.req.xml sample SOAP/XML request
- Saving
ChinaStockWebServiceSoap12.getStockImageByCode.res.xml sample SOAP/XML response
- Saving
ChinaStockWebServiceSoap12.getStockImageByteByCode.req.xml sample SOAP/XML
request
- Saving
ChinaStockWebServiceSoap12.getStockImageByteByCode.res.xml sample SOAP/XML
response
- Saving
ChinaStockWebServiceSoap12.getStockImage_kByCode.req.xml sample SOAP/XML
request
- Saving
ChinaStockWebServiceSoap12.getStockImage_kByCode.res.xml sample SOAP/XML
response
- Saving
ChinaStockWebServiceSoap12.getStockImage_kByteByCode.req.xml sample SOAP/XML
request
- Saving
ChinaStockWebServiceSoap12.getStockImage_kByteByCode.res.xml sample SOAP/XML
response
- Saving
ChinaStockWebServiceSoap12.getStockInfoByCode.req.xml sample SOAP/XML request
- Saving
ChinaStockWebServiceSoap12.getStockInfoByCode.res.xml sample SOAP/XML response
- Saving
ChinaStockWebServiceSoap12.nsmap namespace mapping table
-
- Compilation
successful
-
- 接着,就可以利用存根程序提供的接口编写客户端程序了,过程相当简单。
#include "soapH.h"
#include "ChinaStockWebServiceSoap12.nsmap"
int main(int argc, char **argv) {
if ( argc != 2 ) {
printf("Usage: %s stock_code\n", argv[0]);
exit(-1);
}
struct soap soap;
soap_init(&soap);
struct _ns1__getStockInfoByCode request;
struct _ns1__getStockInfoByCodeResponse response;
request.theStockCode = argv[1];
if ( soap_call___ns3__getStockInfoByCode(&soap, NULL, NULL, &request, &response) == SOAP_OK ) {
int element_counter = response.getStockInfoByCodeResult->__sizestring;
int i = 0;
for ( i = 0; i < element_counter; i++ ) {
switch ( i ) {
case 0 : printf("Stock code : "); break;
case 1 : printf("Stock name : "); break;
case 2 : printf("Timestamp : "); break;
case 3 : printf("Latest price : "); break;
case 4 : printf("Closing price T-1 : "); break;
case 5 : printf("Opening price : "); break;
case 6 : printf("Ups and downs : "); break;
case 7 : printf("Mininum price : "); break;
case 8 : printf("Maxinum price : "); break;
case 9 : printf("Amount of up/down : "); break;
case 10 : printf("Trading volume : "); break;
case 11 : printf("Trading amount : "); break;
case 12 : printf("Buy price : "); break;
case 13 : printf("Sell price : "); break;
case 14 : printf("Agency trans : "); break;
case 15 : printf("Buy 1 : "); break;
case 16 : printf("Buy 2 : "); break;
case 17 : printf("Buy 3 : "); break;
case 18 : printf("Buy 4 : "); break;
case 19 : printf("Buy 5 : "); break;
case 20 : printf("Sell 1 : "); break;
case 21 : printf("Sell 2 : "); break;
case 22 : printf("Sell 3 : "); break;
case 23 : printf("Sell 4 : "); break;
case 24 : printf("Sell 5 : "); break;
default : break;
}
printf("%s\n", response.getStockInfoByCodeResult->string[i]);
}
}
else {
soap_print_fault(&soap, stderr);
}
soap_destroy(&soap);
soap_end(&soap);
soap_done(&soap);
return 0;
}
-
- 基本上都是套用差不多的格式,不清楚具体参数意义的话,可以参考soapcpp2生成的存根程序及其头文件。把上述代码保存为stock.c,编译命令是:
- gcc -O2
-o stock stock.c soapC.c soapClient.c ../../stdsoap2.c -I../.. -L../.. –lgsoap
-
- 可以看到,编译时,除了stock.c,还需要包括存根程序soapC.c和soapClient.c,以及gSOAP运行时引擎stdsoap2.c,另外还需要指定头文件搜索路径、库文件搜索路径,以及告诉编译器,链接libgsoap
-
- 一切正常的话,就大功告成了:
- -bash-3.2$ ./stock sh600000
- Stock
code : sh600000
- Stock
name : 浦发银行
- Timestamp : 2010-07-08 15:02:07
- Latest
price : 13.79
- Closing
price T-1 : 13.76
- Opening
price : 13.88
- Ups and
downs : 0.03
- Mininum
price : 13.73
- Maxinum
price : 14.06
- Amount of
up/down : 0.22%
- Trading
volume : 451017.84
- Trading
amount : 62602.5809
- Buy
price : 13.78
- Sell
price : 13.79
- Agency
trans : 34.07%
- Buy 1
: 13.78 / 1622.88
- Buy 2
: 13.77 / 687.10
- Buy 3
: 13.76 / 785.00
- Buy 4
: 13.75 / 1430.00
- Buy 5
: 13.74 / 264.00
- Sell
1 : 13.79 / 33.70
- Sell
2 : 13.80 / 64.17
- Sell
3 : 13.81 / 290.80
- Sell
4 : 13.82 / 1318.70
- Sell
5 : 13.83 / 647.70
http://blog.csdn.net/yui/archive/2010/07/08/5721877.aspx