工作需要用vc做一个webservice客户端,学习了一下gSoap。
gSoap下载地址?http://sourceforge.net/projects/gsoap2/files/
1. 下载后解压到本地硬盘,找到F:Work Foldergsoap-2.8gsoapbinwin32目录
看到下面有wsdl2h.exe和soapcpp2.exe可执行文件
2. 运行D:gsoap-2.8gsoapbinwin32
???? wsdl2h -o?TermInfo.h TermInfo.wsdl
3. 运行D:gsoap-2.8gsoapbinwin32
??? soapcpp2 -I D:gsoap-2.8gsoapImport TermInfo.h
?? ?注意以上红色路径指定import文件夹路径,否则会看到soapcpp2提示:Critical error: #import: Cannot open file "stlvector.h" for reading.那是因为我们的头文件使用了STL(wsdl2h 没用-s选项),这时要使用-I选项指定gSOAP的 import文件路径
将生成以下文件
TermInfoHttpBinding.example.req.xml
TermInfoHttpBinding.example.res.xml
TermInfoHttpBinding.nsmap
soapC.cpp
soapClient.cpp?
soapClientLib.cpp?
soapBankingHttpTermInfoObject.h
soapBankingHttpTermInfogProxy.h
soapH.h?
soapServer.cpp?
soapServerLib.cpp?
soapStub.h
将生成下面这些文件
- 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代码,这两个文件就不会生成)
综上所述
- 如果编写服务器端,项目里应该加入soapServerLib.c,代码里包含头文件soapH.h
- 如果编写客户端,项目里应该加入soapClientLib.c,代码里包含头文件SoapH.h(或xxxxProxy.h)
- 当然,还要加入gsoap库里的stdsoap2.cpp文件(如果是写C代码,则加入stdsoap2.c)
?
?
wsdl2h常用选项
- -o?文件名,指定输出头文件
- -n?名空间前缀 代替默认的ns
- -c?产生纯C代码,否则是C++代码
- -s?不要使用STL代码
- -t?文件名,指定type map文件,默认为typemap.dat
- -e?禁止为enum成员加上名空间前缀
type map文件用于指定SOAP/XML中的类型与C/C++之间的转换规则,比如在wsmap.dat里写
?
?
soapcpp2常用选项
- -C?仅生成客户端代码
- -S 仅生成服务器端代码
- -L?不要产生soapClientLib.c和soapServerLib.c文件
- -c?产生纯C代码,否则是C++代码(与头文件有关)
- -I?指定import路径
- -x?不要产生XML示例文件
- -i?生成C++包装,客户端为xxxxProxy.h(.cpp),服务器端为xxxxService.h(.cpp)。
?
4. 拷贝以下文件到vc工程目录
soapC.cpp
soapH.h
soapClient.cpp
soapStub.h
BankingHttpBinding.nsmap
stdsoap2.h (在gsoap根目录)
stdsoap2.cpp (在gsoap根目录)
5. 将以上文件加入vc工程里,选择soapC.cpp,soapClient.cpp,stdsoap2.cpp右击鼠标Property ->c++->Precompiled Headers,选择Not using precompiled headers (预编译头)
准备工作完成,开始编写代码,下面是个简单的例子:
#include "stdafx.h"
#include <stdio.h>
#include "soapH.h"
#include "TermInfoHttpBinding.nsmap"
#include <iostream>
#include ?<string>
using namespace std;
int main(int argc,char **argv)?{
?? ?struct soap clientSOAP; //初始化gSoap运行时环境变量,只需初始化一次
?? ?struct _ns1__UpdateByMacToFtp addUserMsg;?
?? ?struct _ns1__UpdateByMacToFtpResponse addUserResponse;?
?? ?soap_init(&clientSOAP);?
?? ?string sd="00AC77443674,1010081856,1011051606,OK,OK";
?? ?addUserMsg.in0= &sd;
?? ?//远程web服务的endpoint URL .不要带WSDL
?? ?const char* server="http://192.168.100.1:8080/TermService/services/TermInfo";
?? //该函数是客户端调用的主要函数,函数名是接口函数名前面加上soap_call_
?? if(soap_call___ns1__UpdateByMacToFtp(&clientSOAP,server,NULL,&addUserMsg,&addUserResponse) == SOAP_OK)?
?? ?{?
string out=*addUserResponse.out;
printf("%sn",out.c_str());?
?? ?}else?
?? ?{?
?? ? ? ? ? ?printf("Errorn");?
?? ?} ? ? ? ? ?
?? ?soap_destroy(&clientSOAP);?
?? ?soap_end(&clientSOAP);?
?? ?soap_done(&clientSOAP);?
?? ?getchar();
?? ?return 0;?
}