使用GSoap生成Onvif开发框架

1,155 阅读4分钟

前言

本文介绍如何在windows下利用Gsoap生成具有鉴权功能的Onvif开发框架代码(C语言版本)。

PS: 生成的代码在linux下可直接使用,只需要将步骤6."onvif项目搭建"改用cmake编译即可。

生成过程

1.下载gSoap

sourceforge.net/projects/gs… 打开链接,选择版本2.8.121 download_link.png

2. 添加环境变量

使用gSoap生成onvif源码,须用到wsdl2h.exe和soapcpp2.exe这两个工具,所以先将其目录加入环境变量,方便后续使用。下载Gsoap并解压,进入gsop\bin\win64目录,可以看到工程中已经携带了windows下编译好的gSoap工具。

tools.png

依次右键“我的电脑”----“属性”---“高级系统设置”,在弹出的“环境变量”配置窗口中,选择“系统变量”下的“Path”,双击编辑“Path”值,弹出下图所示,添加目录即可。

enviroment.png

3. 工具介绍

wsdl2h工具的作用是根据wsdl文件生成 c/c++ 头文件;可以在命令中执行wsdl2h -h 查看支持的参数选项; wsdl为web services 描述语言,可以简单理解为用来描述支持onvif服务的摄像机提供的接口;

soapcpp工具用于将上述头文件生成c/c++ 源文件; 同样可以在命令中执行soapcpp2 -h 查看支持的参数选项;

这里贴一个wsdl2h -h的命令截图,仅供参考:

help.png

4.生成onvif开发所需头文件

先创建一个目录,用于存放后续生成的Onvif开发所需的头文件和源文件,本文创建的是generated目录。 然后把下面的命令放到.bat文件中执行, .bat文件与generated目录同级; 当然也可以手动拷贝; 执行之前需要修改typemap.dat

set GSOAP_PATH=E:\workspace\thirdparty\gsoap_2.8.121\gsoap-2.8\gsoap
cd generated
copy %GSOAP_PATH%\typemap.dat .\
copy %GSOAP_PATH%\stdsoap2.h .\
copy %GSOAP_PATH%\stdsoap2.c .\
copy %GSOAP_PATH%\dom.c .\
wsdl2h -o onvif.h -c -s -t ./typemap.dat <http://www.onvif.org/onvif/ver10/device/wsdl/devicemgmt.wsdl> <http://www.onvif.org/onvif/ver10/media/wsdl/media.wsdl> <http://www.onvif.org/onvif/ver10/event/wsdl/event.wsdl> <http://www.onvif.org/onvif/ver10/display.wsdl> <http://www.onvif.org/onvif/ver10/deviceio.wsdl> <http://www.onvif.org/onvif/ver20/imaging/wsdl/imaging.wsdl> <http://www.onvif.org/onvif/ver20/ptz/wsdl/ptz.wsdl> <http://www.onvif.org/onvif/ver10/receiver.wsdl> <http://www.onvif.org/onvif/ver10/recording.wsdl> <http://www.onvif.org/onvif/ver10/search.wsdl> <http://www.onvif.org/onvif/ver10/network/wsdl/remotediscovery.wsdl> <http://www.onvif.org/onvif/ver10/replay.wsdl> <http://www.onvif.org/onvif/ver20/analytics/wsdl/analytics.wsdl> <http://www.onvif.org/onvif/ver10/analyticsdevice.wsdl> <http://www.onvif.org/ver10/actionengine.wsdl> <http://www.onvif.org/ver10/pacs/accesscontrol.wsdl> <http://www.onvif.org/ver10/pacs/doorcontrol.wsdl>

成功后,会在generated目录下生成onvif.h头文件, 因为要支持鉴权功能,需要在onvif.h文件中加入头文件"wsse.h",如下图所示:

auth.png

参数说明:

-o onvif.h 指定了生成的头文件名称,可以根据需要自己命名。
-c 指定了生成c语言源文件,默认生成c++源文件
-s 指定了不产生STL相关代码(产生的源码中不使用std::stringstd::vector)
-t 是typemap.dat的标识

注意事项:

执行wsdl2h -o onvif.h -c -s -t ./typemap.dat命令前,需要修改typemap.dat, 在文件的最后添加如下一行,否则后续项目开发时可能会编译报错

xsd__duration = #import "custom/duration.h" | xsd__duration

相关报错参考: 无法解析的外部符号 "struct timeval * __cdecl soap_in_xsd__dateTime等问题,是因为你的项目中没有添加duration.c和duration.h;

错误链接:blog.csdn.net/qq_36351159…

但是添加duration.c和duration.h后仍然可能报错,这个时候就需要修改typemap.dat,重新生成头文件了

错误链接:blog.csdn.net/qq_36351159…

5. 生成onvif开发所需要的源码

set GSOAP_PATH=E:\workspace\thirdparty\gsoap_2.8.121\gsoap-2.8\gsoap
cd generated
soapcpp2 -2cCL onvif.h -x -I%GSOAP_PATH% -I%GSOAP_PATH%\import -I%GSOAP_PATH%\custom -I%GSOAP_PATH%\extras -I%GSOAP_PATH%\plugin

执行成功后,会在generated目录下生成以下几个文件:

soapC.c soapClient.c soapH.h soapStub.h 参数说明:

-2 指定使用soap 1.2版本,如果不加此选项,某些情况下可能会出现使用soap1.1的情况。
-c 指定了生成c语言源文件 ,默认生成c++源文件
-C 指定只生成客户端源码,否则会同时生成服务端源码,如果你做onvif 服务开发,则不要指定此选项;
-L 指定不生成lib文件,即不生成 soapClientLib.c, 没必要生成这个;

备注:

生成源码时,可能会报"SOAP_ENV__Fault already declared at wsa.h中"的错误,这是因在wsa5.h文件的最末尾处也声明了SOAP_ENV__Fault结构体,解决方案就是注释掉wsa5.h中的此结构体的声明。

err.png

6.onvif项目搭建

开发具有鉴权功能的onvif客户端,只有上述4个文件还不够,还需要将gsop\plugin gsop\custom等目录下的一些文件拷贝到你的工程目录下

set GSOAP_PATH=E:\workspace\thirdparty\gsoap_2.8.121\gsoap-2.8\gsoap
cd generated
copy %GSOAP_PATH%\custom\duration.c .\
copy %GSOAP_PATH%\custom\duration.h .\
copy %GSOAP_PATH%\custom\struct_timeval.c .\
copy %GSOAP_PATH%\custom\struct_timeval.h .\
copy %GSOAP_PATH%\plugin\mecevp.c .\
copy %GSOAP_PATH%\plugin\mecevp.h .\
copy %GSOAP_PATH%\plugin\smdevp.c .\
copy %GSOAP_PATH%\plugin\smdevp.h .\
copy %GSOAP_PATH%\plugin\threads.c .\
copy %GSOAP_PATH%\plugin\threads.h .\
copy %GSOAP_PATH%\plugin\wsaapi.c .\
copy %GSOAP_PATH%\plugin\wsaapi.h .\
copy %GSOAP_PATH%\plugin\wsseapi.c .\
copy %GSOAP_PATH%\plugin\wsseapi.h .\

我尝试按网上说的修改.c为.cpp文件,尝试直接在c++工程中引用,但编译报错,所以放弃了直接在c++工程中引用上述文件。而是利用上述源码二次封装成一个C库,封装定义并导出自己需要的C接口,比如设备发现接口、获取rtsp url的接口等,然后再在C++中调用。 如下图所示,利用vs2017创建一个c动态库工程,红色框内的文件为上述目录中的文件; 玫红色框内的就是要二次封装和导出的c接口,供C++调用。

code.png

因为鉴权需要依赖OpenSSL, 所以需先安装openssl库,自行百度安装;并在vs2017中设置如下工程属性:

1.png

2.png

3.png

4.png