gsoap生成onvif c/c++代码框架
1. 到官网下载gsoap源码
下载地址:https://sourceforge.net/projects/gsoap2/
我当前下载的版本是gsoap_2.8.134
2. 编译gsoap
编译环境:Ubuntu18.04
- 解压
unzip gsoap_2.8.134.zip
- 配置
cd gsoap_2.8.134
mkdir install
./configure --prefix=/home/james/workdir/gsoap-2.8/install
prefix替换为自己的安装路径
- 编译安装
make && make install
3. 生成的工具
进入/home/james/workdir/gsoap-2.8/install/bin目录下,里面就是生成的工具了
wsdl2h的作用是根据WSDL文件生成一个gsoap用到的头文件,wsdl2h 常用指令:
- -o filename.h 将wsdl转化为filename.h头文件。
- -s 不生成STL代码
- -c 生成纯C风格的头文件,这将去除C++的一些特性
- -n name 使用name代替默认前缀ns
- -t filename.dat 使用filename.dat代替默认的typemap.dat文件
- -zX 兼容之前的X版本
soapcpp2的作用是根据头文件自动生成调用远程 SOAP服务的客户端代码(称为存根:Stub)和提供SOAP服务的框架代码(称为框架:Skeleton),另外它也能从头文件生成WSDL文件。其中,soapH.h and soapC.c包含了数据类型的描述,soapClient.c给客户端使用,soapServer.c给服务端使用。
-
-i 生成server的proxy和object,这种object继承于soap struct。
-
-j 和-i类似,区别在于生成的代理类不继承于soap struct,而是包含了包含了一个soap结构的指针。此种方式生存的代理类便于互相通信
-
-C 仅生成客户端client代码
-
-S 仅生成服务端server代码
-
-x 不生成xml文件。不用此项的话,将对头文件中定义的每个operation生成一个描述性的xml文件
-
-L 不生成soapClientLib文件和soapServerLib文件
-
-p name 修改文件名前缀,代替soap
-
-q name 指定代理类和对象使用的名空间name,包含文件名前缀
-
编译问题
(1)缺少autoconf
(CDPATH="${ZSH_VERSION+.}:" && cd . && /bin/bash '/home/james/workdir/gsoap-2.8/missing' autoheader)
/home/james/workdir/gsoap-2.8/missing: line 81: autoheader: command not found
解决:
sudo apt install autoconf
(2)缺少openssl
In file included from stdsoap2_ssl.c:75:0:
stdsoap2.h:903:11: fatal error: openssl/bio.h: No such file or directory
# include <openssl/bio.h>
解决:
sudo apt-get install libssl-dev
(3)缺少zlib
In file included from stdsoap2_ssl.c:75:0:
stdsoap2.h:956:11: fatal error: zlib.h: No such file or directory
# include <zlib.h>
解决:
sudo apt install zlib1g-dev
(4)使用生成的duration.c时,LONG64报错
解决:
onvif_code目录下
vim ../../gsoap/typemap.dat
取消下面这行代码的注释
xsd__duration = #import "custom/duration.h" | xsd__duration
4. 生成onvif c/c++框架代码
(1)准备好WSDL文件
WSDL官网网址:点击这里WSDL文件地址
地址:https://www.onvif.org/profiles/specifications/
可以选择需要的wsdl文件下载,或者直接使用对应的https网址
(2)使用wsdl2h生成onvif.h头文件
- 执行以下步骤生成头文件
onvif_code是自定义目录,用于存放生成的onvif.h和后续的.c文件
cd /home/james/workdir/gsoap-2.8/install
mkdir onvif_code
cd onvif_code
mkdir onvif
mkdir onvif_soap
直接使用https网址的wsdl生成onvif.h头文件
../bin/wsdl2h -c -x -t ../../gsoap/typemap.dat -o onvif/onvif.h \
https://www.onvif.org/ver10/device/wsdl/devicemgmt.wsdl \
https://www.onvif.org/onvif/ver10/network/wsdl/remotediscovery.wsdl \
https://www.onvif.org/onvif/ver20/ptz/wsdl/ptz.wsdl \
https://www.onvif.org/onvif/ver20/imaging/wsdl/imaging.wsdl \
https://www.onvif.org/onvif/ver10/deviceio.wsdl \
https://www.onvif.org/onvif/ver10/media/wsdl/media.wsdl \
https://www.onvif.org/onvif/ver20/media/wsdl/media.wsdl
使用下载好的wsdl生成
../bin/wsdl2h -c -x -t ../../gsoap/typemap.dat -o onvif/onvif.h ../wsdl/remotediscovery.wsdl ../wsdl/devicemgmt.wsdl ../wsdl/media.wsdl ../wsdl/media2.wsdl ../wsdl/imaging.wsdl ../wsdl/ptz.wsdl
现在可以看到生成的onvif.h在onvif_code/onvif目录下
- 修改onvif.h,支持鉴权,即可以使用soap_wsse_add_UsernameTokenDigest等鉴权相关的函数
增加#import “wsse.h”
- 修改import/wsa5.h文件
vim ../../gsoap/import/wsa5.h
找到int SOAP_ENV__Fault结构体定义,将名字改为int SOAP_ENV__Fault_XXX以避免冲突,保存退出编辑
(3)使用soap2cpp生成c/c++客户端代码文件
生成的文件在onvif目录下
../bin/soapcpp2 -2 -x -C onvif/onvif.h -L -I ../../gsoap/import -I ../../gsoap/ -donvif
在onvif_code/onvif目录下生成了客户端代码
留下wsdd.nsmap文件,其他的nsmap文件内容都是一样的,删除掉即可。
拷贝需要的源文件到onvif_code/onvif_soap目录
编写脚本copy.sh
#!/bin/sh
cd /home/james/workdir/gsoap-2.8
cp gsoap/stdsoap2.c gsoap/stdsoap2.h gsoap/plugin/wsaapi.c gsoap/plugin/wsaapi.h gsoap/custom/duration.c gsoap/custom/duration.h install/onvif_code/onvif_soap
cp gsoap/custom/struct_timeval.* install/onvif_code/onvif_soap
# 用于授权验证的一些文件
cp gsoap/dom.c gsoap/plugin/mecevp.* gsoap/plugin/smdevp.* gsoap/plugin/threads.* gsoap/plugin/wsseapi.* install/onvif_code/onvif_soap
执行copy.sh后,此时的onvif_code/onvif_soap目录的文件如下
到这里,onvif客户端的代码框架就生成了。
(4)编译成库
在onvif_code目录下新建CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project(ONVIF_SOAP_LIB)
set(CMAKE_C_COMPILER "gcc")
set(CMAKE_CXX_FLAGS "-g -O0")
set(LIB_SOAP_SRC
onvif_soap/struct_timeval.c
onvif_soap/duration.c
onvif_soap/wsaapi.c
onvif_soap/dom.c
onvif_soap/wsseapi.c
onvif_soap/smdevp.c
onvif_soap/mecevp.c
onvif_soap/threads.c
onvif_soap/stdsoap2.c)
add_library(onvif_soap STATIC ${LIB_SOAP_SRC})
target_link_libraries(onvif_soap PUBLIC ssl crypto)
target_compile_definitions(onvif_soap PUBLIC WITH_OPENSSL WITH_DOM)
target_include_directories(onvif_soap PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/onvif ${CMAKE_CURRENT_SOURCE_DIR}/onvif_soap)
add_library(onvif STATIC onvif/soapC.c onvif/soapClient.c)
target_include_directories(onvif PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/onvif)
target_link_libraries(onvif PUBLIC onvif_soap)
执行以下命令生成库
mkdir build
cd build
cmake ..
make
后续就可以通过库的方式进行使用。
THE END!
参考链接:
https://blog.csdn.net/noevil/article/details/133084718