最近在交叉编译gsoap的时候总出现错误,仔细研究试验记录成功编译步骤。
1.解压gsoap-2.8,复制两份,命名为gsoap-x86和gsoap-arm
2.编译x86下库,进入gsoap-x86目录,执行 ./configure ,make, su -c 'make install'
3.编译arm下库,进入gsoap-arm:
./configure --prefix=/usr/local/gsoap-arm --host=arm-hisiv300-linux
然后修改config.h,
(1). 将#define malloc rpl_malloc 屏 蔽;(2).将#define HAVE_MALLOC 0 更改为:#define HAVE_MALLOC 1
4然后执行make,可能会出现错误:
../../gsoap/src/soapcpp2: cannot execute binary file
原因是需要使用便生成的soapcpp2,但是x86下不能运行arm下的执行程序,于是就把这个文件重名名,
然后把x86下的gsoap/src/soapcpp2文件复制一份过来,然后继续执行make,编译成功,然后再把这个文件用以前备份的替换掉,当然也可以直接删除,然后在gsoap/src/目录下执行make,重新生成即可
5.执行make install
编译中遇到的问题;
遇到的编译出错问题网上均可以找到答案.
make环境问题:
(1)ylwrap: line 176: yacc: command not found。yacc是一个生成语法分析器的工具。
#yum install yacc
(2)missing: line 81: flex: command not found。
#yum install flex (需重新配置安装路径)
(3)/usr/bin/ld: cannot find -ly。
#yum install yum install bison-devel
(4)../../gsoap/stdsoap2.h:690:19:error:zlib.h:No such file or directory
#yum install zlib-devel
(5)error: openssl/bio.h: No such file or directory
#yum install openssl-devel
注意,在编译wsdl中,要用到zlib 和ssl库,需要用hisi编译器编译成功并放到wsdl(/gsoap-2.8/gsoap/wsdl)目录下放可编译通过。
生成C++文件
一. 开发环境准备
1. 从gSoap官方网站http://gsoap2.sourceforge.net 下载gSoap工具包。
本例下载的是2.7.15的版本。
2. 根据说明文档(README)配置安装gSoap工具包。
说明: 一般下载的gSoap工具包中已经包含了生成Web Service客户端需要用到的两个工具(可执行文件):wsdl2h和soapcpp2,一般在gsoap/bin/linux386下。只是默认情况下,wsdl2h并不支持SSL,即无法访问HTTPS站点,且这两个工具的版本一般也要低于所在gSoap工具包的版本。
所以如果想要支持SSL等更多功能,就需要自己重新配置编译该gSoap工具包,以生成新的sdl2h和soapcpp2。
反之,如果下载的gSoap工具包中自带的wsdl2h和soapcpp2已经满足了你的需求,就可以不必再配置编译gSoap工具包了;而是直接使用工具包自带的wsdl2h和soapcpp2。
二. 开发linux下Web Service C/C++客户端
这里,我们直接采用gSoap工具包自带的wsdl2h和soapcpp2工具。
1. 基本流程
从Web服务提供者处获取Web Service的WSDL文件,通常是一个URL,
如:http://www.cs.fsu.edu/~engelen/calc.wsdl
当然也可以是一个WSDL形式的XML文件。
2. 使用gSoap工具wsdl2h,根据WSDL生成一个C/C++语法结构的头文件。
如:wsdl2h -s -o SommocService.h http://www.cs.fsu.edu/~engelen/calc.wsdl
这一步将会得到一个头文件,如:calc.h
该步的目的:实现WSDL文件到.h文件的数据映射。
3. 使用gSoap的预编译器soapcpp2,根据上一步得到的头文件来生成存根文件(soapStub.h)和客户端代码框架。
如:soapcpp2 -i -x -C -L calc.h
./soapcpp2 -i -x -C -p Hisi_ SommocService.h
这一步将会得到几个. nsmap、.h和.cpp文件,如:calc.nsmap、soapC.cpp、soapH.h、soapStub.h、soapcalcProxy.cpp、soapcalcProxy.h
该步的目的:生成相应的底层通信代码。
4. 实现客户端例程
在这一步可以简单地编写一个main函数,如:(注意包含的头文件)
#include "calc.nsmap"
#include "soapcalcProxy.h" //该头文件已经包含了soapH.h
int main(void)
{
printf("very good!\n");
calcProxy service;
{
double result;
if(service.pow(2, 10, result) == SOAP_OK)
{
std::cout << "The value of 2^10 is " << result << std::endl;
}
}
return 0;
}
5. 用gcc编译客户端,生成可执行代码
编译需要的文件有:第3步生成的所有文件、第4步编写的main函数所在的文件,以及gsoap目录下的stdsoap2.h和stdsoap2.cpp文件共9个文件。
如:calc.nsmap、soapC.cpp、soapH.h、soapStub.h、soapcalcProxy.cpp、soapcalcProxy.h、stdsoap2.cpp、stdsoap2.h、main.cpp。
三、注意事项
注1 :wsdl2h的用法(WSDL/schema 解析和代码生成器)
wsdl2h [opt] 头文件名 WSDL文件名或URL
wsdl2h常用选项
-o 文件名,指定输出头文件
-n 名空间前缀 代替默认的ns
-c 产生纯C代码,否则是C++代码
-s 不要使用STL代码
-t 文件名,指定type map文件,默认为typemap.dat
-e 禁止为enum成员加上名空间前缀
type map文件用于指定SOAP/XML中的类型与C/C++之间的转换规则,比如在wsmap.dat里写。
在本例中,使用的是:wsdl2h -s -o calc.h http://www.cs.fsu.edu/~engelen/calc.wsdl
参数s就表示生成不带STL的C/C++语法结构的头文件calc.h。
如果不用s就会生成带STL的头文件,这样,在后边的编译中需要加入STL的头
stlvector.h,位于:gsoap/import/目录下。
注2 :soapcpp2的用法(编译和代码生成器)
soapcpp2 [opt] 头文件名
soapcpp2常用选项
-C 仅生成客户端代码
-S 仅生成服务器端代码
-L 不要产生soapClientLib.c和soapServerLib.c文件
-c 产生纯C代码,否则是C++代码(与头文件有关)
-I 指定import路径(见上文)
-x 不要产生XML示例文件
-i 生成C++封装(代理),客户端为xxxxProxy.h(.cpp),服务器端为xxxxService.h(.cpp)。
本例中,使用的是:soapcpp2 -i -x -C -L calc.h
注3 :gSoap工具wsdl2和soapcpp所生成文件的简单分析
(1) wsdl2生成的具有C/C++语法结构的头文件,其作用就是:将XML语法结构的WSDL文件映射为C/C++语法结构的.h文件;并为下一步做准备。
(2) soapcpp(采用参数:-i -x -C -L)生成的文件共有6个文件:PlayerBeanPortBinding.nsmap、soapC.cpp、soapH.h、 soapPlayerBeanPortBindingProxy.cpp、soapPlayerBeanPortBindingProxy.h、 soapStub.h。
a. PlayerBeanPortBinding.nsmap文件
该文件的作用:An XML-to-C/C++ namespace mapping table,即WSDL文件与生成的客户端代码框架的一个名字空间的映射表。
b. soapStub.h
该文件就是直接由wsdl2生成的头文件转化而来,它详细定义了WSDL所描述的各项服务和数据结构。
它是soap的存根文件,定义了由wsdl2生成的头文件里对应的远程调用模型(RPC)。
c. soapPlayerBeanPortBindingProxy.和soapPlayerBeanPortBindingProxy.cpp
这两个文件是客户端代码的一个简单封装,它封装了底层通信,并向外提供一个很简单的界面,该界面展示了用户能够使用的所有服务(由WSDL所描述)。
d. soapH.h和soapC.cpp
这个两个文件是soap的序列和反序列化代码,
注4 :设置字符编码
在利用gSoap编写Web Service客户端和服务器端的程序时,需要设置其编码
方式。接口为:soap_set_mode,其实它是就是一个宏:
#define soap_set_mode(soap, n) ((soap)->imode |= (n), (soap)->omode |= (n))
如果要设置为UTF8
可以这样调用:soap_set_mode(&soap, SOAP_C_UTFSTRING);
详细信息可参考该宏所在文件:stdsoap2.h