gSoap开发包的下载地址http://sourceforge.net/projects/gsoap2
下载最新gSoap程序包
解压后在\gsoap\bin\win32(windowsXP下,其它操作系统就自己选择)下找到 编译器soapcpp2.exe 和wsdl解析工具 wsdl2h.exe
开发客户端和服务器端程序
结合例子说明过程
执行时,会产生如下错误:Critical error: #import: Cannot open file "ns1.h" for reading.
错误原因是devicemgmt.h里有如下代码 #import "ns1.h" // ns1 = <http://www.w3.org/2005/08/addressing>
解决办法如果通过下面方式避免这个问题:
根据wsdl生成头文件时,加1个xsd文件
wsdl2h.exe -o devicemgmt.h http://www.onvif.org/onvif/ver10/device/wsdl/devicemgmt.wsdl http://www.w3.org/2006/03/addressing/ws-addr.xsd
wsdl2h常用选项:
- -o 文件名,指定输出头文件
- -c 产生纯C代码,否则是C++代码
- -s 不要使用STL代码
- -t 文件名,指定type map文件,默认为typemap.dat
typemap文件用于指定SOAP/XML中的类型与C/C++之间的转换规则,比如在wsmap.dat里写
<span style="font-size:12px;"> xsd__string = | std::wstring | wchar_t*</span>
那么SOAP/XML中的string将转换成std::wstring或wchar_t*,这样能更好地支持中文
例:
wsdl2h -o ayandy.h -n ay -t wsmap.dat http://www.ayandy.com/Service.asmx?WSDL
从http://www.ayandy.com/Service.asmx?WSDL 生成ayandy.h文件,名空间为ay,使用wsmap.dat指定的转换规则。
wsdl2h生成的头文件里的变量、类型等名称的前面都会加上名空间前缀,以两个下划线分隔。如上面的命令生成的头文件,有这样的定 义:
前面的ayandy1__的是名空间前缀,用以防止名称冲突。 wsdl2h的-n选项可以改变这个名空间前缀(默认为ns)。对于枚举ay1__theDayFlagEnum内 的成员, 如果嫌它太长的话,可以用-e命令选项禁止加入名空间前缀。
d) 回车 运行吧,看提示信息,没有提示故障的话,会生成devicemgmt.h文件(wsdl2h.exe所在的目录)
执行时,会产生如下错误:Critical error: #import: Cannot open file "stl.h" for reading.
Hint :use option -I<path><for example -Igsoap/import;gsoap/custom:.>
产生原因:你的头文件使用了STL(wsdl2h 没用-s选项),这时要使用-I选项指定gSOAP的 import文件路径。你的头文件使用了STL(wsdl2h 没用-s选项)
解决办法:添加 -I选项,指定import目录的stl.h文件的路径 soapcpp2.exe -I ..\..\import devicemgmt.h
soapcpp2常用选项
- -C 仅生成客户端代码
- -S 仅生成服务器端代码
- -L 不要产生soapClientLib.c和soapServerLib.c文件
- -c 产生纯C代码,否则是C++代码(与头文件有关)
- -I 指定import路径(见上文)
- -x 不要产生XML示例文件
- -i 生成C++包装,客户端为xxxxProxy.h(.cpp),服务器端为xxxxService.h(.cpp)。
h) 编译成功,生成的框架文件保存位置与devicemgmt.h 在同一目录下
其中
- soapStub.h // soap的存根文件,定义了devicemgmt.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
- DeviceBinding.nsmap // 名空间定义,服务器端与客户端都要包含它
综上所述
- 如果编写服务器端,项目里应该加入soapServerLib.c,代码里包含头文件soapH.h
- 如果编写客户端,项目里应该加入soapClientLib.c,代码里包含头文件SoapH.h)
- 当然,还要加入gsoap库里的stdsoap2.cpp文件(如果是写C代码,则加入stdsoap2.c)