**************************************************************************
gsoap的官网地址:https://www.genivia.com,包含商业版,以及GPLv2的开源版本。
1、下载地址:https://www.genivia.com/download/gsoap-2.8.54.zip,发布版本中包含平台无关的源代码,预构建的windows、MAC OS的可执行二进制。
也可以去gSOAP下载网址:http://sourceforge.net/projects/gsoap2
2、需要用到gsoap的soapcpp2 与wsdl2h 来生成自己的webservice调用的数据结构与应用。
解压,在gsoap/bin 目录可以看到自带的MAC OS与windows 编译库。
soapcpp2:gsoap代码生成器。
wsdl2h:自身是gsoap的应用,解析WSDL,XML模式,SOAP/XML。通过wsdl2h 解析 webservice的wsdl文件,可以生成对应的调用代码。
将wsdl文件转换为 头文件。
3、 Unix/Linux 上安装gsoap
上传并解压gsoap-2.8.54.zip,在解压目录下
./configure
make
sudo make install
在gsoap目录下生成soapcpp2,wsdl2h,make install将其复制到/usr/local/bin/目录下。
4、生成自己应用对应的代码文件。
网管应用的wsdl文件已提供URL,如:http://10.118.203.187:58080/monitor/rpc/kpi?wsdl
使用 wsdl2h 将wsdl对应的xml 转为 头文件。实现WSDL文件到.h文件的数据映射
注意区分生产c格式,c++格式,wchar格式
wsdl2h -s -o kpi.h http://10.118.203.187:58080/monitor/kpi?wsdl
kpi.h中包含了web rpc 的数据结构
wsdl2h 的各选项定义如下:
选项 |
描述 |
-a |
对匿名类型,产生基于顺序号的结构体名称 |
-c |
生成C代码 |
-f |
对schema扩展,产生flat C++类 |
-g |
产生全局的元素声明 |
-h |
显示帮助信息 |
-I path |
包含文件时指明路径,相当于#import |
-j |
不产生 SOAP_ENV__Header 和SOAP_ENV__Detail 定义 |
-k |
不产生 SOAP_ENV__Header mustUnderstand qualifiers |
-l |
在输出中包含license信息 |
-m |
用 xsd.h 模块来引入类型信息 |
-N name |
用name 来指定服务命名空间的前缀。 |
-n name |
用name 作为命名空间的前缀,取代缺省的ns |
-o file |
输出文件名 |
-q name |
所有的声明采用 name 作命名空间 |
-s |
不产生 STL代码 (即不用 std::string,std::vector) |
-t file |
使用自己指定的type map file而不是缺省的typemap.dat |
-u |
不生成 unions |
-v |
产生详细的输出信息 |
-w |
always wrap response parameters in a response struct |
-y |
为structs,enums产生 typedef定义 |
-_ |
不产生 _USCORE (用UNICODE _x005f代替) |
-? |
显示帮助信息 |
使用soapcpp2 将kpi.h 生成对应的代码。
soapcpp2 -i -x -C -L kpi.h
soapcpp2各选项定义如下:
选项 |
描述 |
-1 |
Soap1.1绑定 |
-2 |
SOAP1.2绑定 |
-C |
只生成客户端代码 |
-S |
只生成服务器端代码 |
-T |
生成自动测试代码 |
-L |
不生成 soapClientLib/soapServerLib |
-a |
用 SOAPAction 和WS-Addressing调用服务器端方法 |
-A |
用 SOAPAction 调用服务器端方法 |
-b |
采用char[N]这样的方式来表示string |
-c |
生成的是C代码,不是C++代码 |
-d < path > |
将代码生成在 < path >下 |
-e |
生成 SOAP RPC 样式的绑定 |
-f N |
File split of N XML serializer implementations per file |
-h |
显示一个简要的用法信息 |
-i |
生成的服务代理类和对象从struct soap继承而来 |
-j |
生成的服务代理类和对象包含struct soap而来(C代码的唯一选择) |
-I < path > |
包含其他文件时使用,指明 < path > (多个的话,用`:'分割),相当于#import ,该路径一般是gSOAP目录下的import目录,该目录下有一堆文件供soapcpp2生成代码时使用。 |
-n |
用于生成支持多个客户端和服务器端(具体内容参考gSOAP文档) |
-p < name > |
生成的文件前缀采用< name > ,而不是缺省的 "soap" |
-q < name > |
C++代码中,所有声明的命名空间 |
-s |
生成的代码在反序列化时,严格检查XML的有效性 |
-t |
生成的代码在发送消息时,采用xsi:type方式 |
-u |
在 WSDL/schema 输出文件中不产生XML注释 |
-v |
显示版本信息 |
-w |
不生成 WSDL 和 schema 文件 |
-x |
不生成 XML 形式的传输消息文件 |
-y |
在XML 形式的传输消息文件中,包含 C/C++类型信息 |
至此,我们已经得到与webservice rpc调用的相关代码与头文件。
编译需要的文件
KpiDataServicePortBinding.nsmap
soapC.cpp
soapH.h
soapStub.h
soapKpiDataServicePortBindingProxy.cpp
soapKpiDataServicePortBindingProxy.h
stdsoap2.cpp –gsoap目录下
stdsoap2.h –gsoap目录下
gsoaptest.cpp
**************************************************************************
gsoap乱码解决:
gsoap客户端有中文发送给服务器,服务器能正常解析,但是服务器中返回的字符串中有中文,客户端显示为乱码,依次使用如下方法尝试解决:
1,代码中初始化soap时:soap_set_mode(&clientSoap,SOAP_C_UTFSTRING);
2, 初始化soap代理类时:
PTZBindingProxy(const char *url, soap_mode iomode);
此处传的入参soap_mode 应为utf8格式:SOAP_C_UTFSTRING
3,以上都不行时,则最后考虑宽字节wchar。使用wsdl2h 编译生成头文件时,就采用编译成支持wchar 格式。
此种方式具体修改方法如下:
3.1,在生成webservice头文件时,先新建文件mytypemap.dat,内容为:
xsd__string = | std::wstring | wchar_t*
3.2,然后用命令生成头文件时,使用如下命令:
wsdl2h -o UploadInfoWebService.h -t mytypemap.dat http://10.252.252.244:8080/grgbackmanager/ws/aio?wsdl
即加上-t mytypemap.data 这个,则在gsoap生成的.h文件中可以看到,std::string已经改为wchar_t*类型了,后面继续用命令生成相应的文件: soapcpp2 UploadInfoWebService.h 然后调用相应的接口时,改为使用wchar_t* 或者std::wstring,则在接收到中文字符串后,能够正常显示中文,不再乱码。
**************************************************************************
##################Onvif的Windows编译##############
1.下载最新gsoap
2.去onvif相关页面
3.打开所有的wsdl,查找对应的schemaLocation="http://xxx/xxx.xsd",下载对应的xsd文件,如:onvif.xsd
4.查找所有的wsdl和xsd,将上述对应schemaLocation和location中关于wsdl和xsd路径里等号后面的内容中关于路径部分的全去掉,因为对应文件已经下载到本地了,比如schemaLocation=“http://docs.oasis-open.org/wsn/b-2.xsd"改为schemaLocation=“b-2.xsd"
6.修改typemap.dat文件,包含如下内容:
# ONVIF recommended prefixes
tds = "http://www.onvif.org/ver10/device/wsdl"
tev = "http://www.onvif.org/ver10/events/wsdl"
tls = "http://www.onvif.org/ver10/display/wsdl"
tmd = "http://www.onvif.org/ver10/deviceio/wsdl"
timg = "http://www.onvif.org/ver20/imaging/wsdl"
trt = "http://www.onvif.org/ver10/media/wsdl"
tptz = "http://www.onvif.org/ver20/ptz/wsdl"
trv = "http://www.onvif.org/ver10/receiver/wsdl"
trc = "http://www.onvif.org/ver10/recording/wsdl"
tse = "http://www.onvif.org/ver10/search/wsdl"
trp = "http://www.onvif.org/ver10/replay/wsdl"
tan = "http://www.onvif.org/ver20/analytics/wsdl"
tad = "http://www.onvif.org/ver10/analyticsdevice/wsdl"
tdn = "http://www.onvif.org/ver10/network/wsdl"
tt = "http://www.onvif.org/ver10/schema"
# OASIS recommended prefixes
wsnt = "http://docs.oasis-open.org/wsn/b-2"
wsntw = "http://docs.oasis-open.org/wsn/bw-2"
wsrfbf = "http://docs.oasis-open.org/wsrf/bf-2"
wsrfr = "http://docs.oasis-open.org/wsrf/r-2"
wsrfrw = "http://docs.oasis-open.org/wsrf/rw-2"
wstop = "http://docs.oasis-open.org/wsn/t-1"
# WS-Discovery 1.0 remapping
wsdd10__HelloType = | wsdd__HelloType
wsdd10__ByeType = | wsdd__ByeType
wsdd10__ProbeType = | wsdd__ProbeType
wsdd10__ProbeMatchesType = | wsdd__ProbeMatchesType
wsdd10__ProbeMatchType = | wsdd__ProbeMatchType
wsdd10__ResolveType = | wsdd__ResolveType
wsdd10__ResolveMatchesType = | wsdd__ResolveMatchesType
wsdd10__ResolveMatchType = | wsdd__ResolveMatchType
# SOAP-ENV mapping
SOAP_ENV__Envelope = struct SOAP_ENV__Envelope { struct SOAP_ENV__Header *SOAP_ENV__Header; _XML SOAP_ENV__Body; }; | struct SOAP_ENV__Envelope
SOAP_ENV__Header = | struct SOAP_ENV__Header
SOAP_ENV__Fault = | struct SOAP_ENV__Fault
SOAP_ENV__Detail = | struct SOAP_ENV__Detail
SOAP_ENV__Code = | struct SOAP_ENV__Code
SOAP_ENV__Subcode = | struct SOAP_ENV__Subcode
SOAP_ENV__Reason = | struct SOAP_ENV__Reason
7.在cmd命令平台使用wsdl2h.exe -t onvif_typemap.dat -o onvif.h devicemgmt.wsdl event.wsdl ptz.wsdl media.wsdl imaging.wsdl receiver.wsdl deviceio.wsdl生成对应的onvif.h文件
8.打开生成的onvif.h,加入#import "wsse.h"用于代码中加解密
9.当生成了对应的头文件后可以用如下命令生成对应的文件(当生成的代码接口调用时返回 soap版本不匹配时,此时需检查soap版本问题,在使用soapcpp2.exe 命令生成代理类时,尝试增加-2 参数,来生成soap1.2的版本)
soapcpp2.exe -i -C -L -x -I D:\Work\gsoap-2.8\gsoap\import -I D:\Work\gsoap-2.8\gsoap onvif.h