基于 gsoap 生成 onvif 服务端框架代码

文章介绍了如何使用gsoap工具生成ONVIF服务端框架代码,包括下载编译gsoap,生成onvif.h,创建服务端框架,以及处理编译错误。重点是通过gsoap将XML、WSDL等集成到代码中,实现设备发现和功能调用。建议初学者先建立一个基础DEMO来理解和学习ONVIF。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章概要

由于项目要求实现 onvif 功能,从对白对接,一开始很多都不懂,后面琢磨琢磨慢慢对它有所了解了。上网查询很多人说一大堆原理,什么是 soap , http,xml, wsdl, WS-Discovery 等等,对于小白来说突然很多新概念直接很头疼。所以还是先建议有一个完整的 demo, 最好自己动手搭建一份框架代码,跑通代码然后慢慢对接功能点,就慢慢了解 onvif 了。
这篇文章主要讲解 gsoap 生成 onvif 框架代码的过程,以及实现设备发现,出图等功能!其实 gsoap 就是一个工具,用它生成 onvif 的框架代码,里面已经把 xml ,wsdl ,WS-Discovery 集合到里面了,我们就管接口怎么调用即可。想深入了解,后面逐渐熟悉慢慢摸索清楚!

soap 相关的接口调用参考: https://www.genivia.com/doc/guide/html/index.html

1、gsoap 的下载编译

gsoap 下载:https://sourceforge.net/projects/gsoap2/ gsoap下载
下载源码之后新建一个 build.sh 脚本执行编译即可:

#!/bin/bash

set -e

case "$1" in
"")
    if [ ! -e $PWD/Makefile ]; then
        ./configure --prefix=$PWD/install
    fi
    make -j8
    make install
    ;;
clean)
    rm -rf $PWD/install # must rm _install first
    make clean
    ;;
distclean)
    make clean
    rm -rf $PWD/install # must rm _install first
    rm -rf $PWD/Makefile
    ;;
esac

生成如下内容,就代表成功了,bin 目录下有我们需要的 wsdl2h、soapcpp2 工具!
在这里插入图片描述
或者你的环境和我的环境有一样地方,编译 gsoap 提示缺什么安装就好了!

2、生成 onvif.h

生成 onvif.h 文件,需要依赖 gsoap-2.8/gsoap/typemap.dat , wsdl2h 这个两个文件,还有依赖 wsdl 文件 wsdl下载链接

wsdl 的相关文件,根据你们的项目需求,下载对应的 wsdl 文件即可:
在这里插入图片描述

注意: 不同 gsoap 版本,typemap.dat 可能需要修改一下,我的是 2.8 版本的就需要修改 typemap.dat 文件末尾添加如下内容:

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  

最好新建一个目录 onvif_code, 把 wsdl 、typemap.dat、wsdl2h、soapcpp2 都放到一起

生成 onvif.h ,一般有两种方式:一种直接下载下来 wsdl 文件(之间有互相依赖的情况,需要下载对应的文件,同时修改l依赖文件为本地路径),另一种直接用链接方式(不用考虑互相依赖,网络因素有可能生成失败,多试几次就好)。我建议是用下载本地的方式生成 onvif.h , 因为后面我们需要对相应的 wsdl 做裁剪的

//下载 wsdl 到本地的方式
./wsdl2h -o onvif.h -c -s -t ./typemap.dat ./wsdl/remotediscovery.wsdl ./wsdl/media.wsdl ./wsdl/media2.wsdl ./wsdl/devicemgmt.wsdl ./wsdl/deviceio.wsdl ./wsdl/analytics.wsdl ./wsdl/event.wsdl ./wsdl/imaging.wsdl

// 链接的方式
./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/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/ver10/media/wsdl/media.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/onvif/ver10/schema/onvif.xsd  \
http://www.onvif.org/ver10/actionengine.wsdl

其中,-c 为产生纯 c 代码,不然为 c++ 代码;-s 为不使用 STL 库, -t 指定 typemap.dat 文件、后面指定需要的 wsdl 文件

注意: 有些伙伴可能有疑问了,wsdl 的相关链接哪里找的?点这里 wsdl链接

在这里插入图片描述
在这里插入图片描述

还有一点就是, 选择本地生成 onvif.h 方式的伙伴,需要修改 wsdl 里面指定依赖文件的路径:

在这里插入图片描述
上面操作都顺利的话,onvif_code 目录下会生成 onvif.h 文件,后面生成框架代码需要 onvif.h 文件

在使用命令通过 onvif.h 生成代码之前,得先确认下是否需要做安全验证, 也就是所谓的鉴权,如果不需要的话,那就可以直接使用命令了,如果需要做鉴权的话,则需要修改 onvif.h , 在 onvif.h 中需要加上
import “wsse.h” // 安全验证

3、生成 onvif 框架代码

生成命令:

 ./soapcpp2 -2 -c onvif.h -x -I ./gsoap-2.8/gsoap/import/ -I ./gsoap-2.8/gsoap/

参数的说明:
-2 //采用SOAP1.2,和 SOAP1.0 版本不同,会导致搜索工具搜索不到
-x //不产生xml文件(可用可不用,xml有一定帮助,但是太多)
-I //为引入路径
-C //只产生客户端代码(注意:C是大写,不推荐有次命令)
其中 /gsoap-2.8/gsoap/import 和 gsoap-2.8/gsoap/ , 引用刚才第一步编译生成 gsoap 的源代码即可

执行命令生成的源文件有:其中有好几个 nsmap 文件,只要 wsdd.nsmap 文件即可
在这里插入图片描述

到此你想编译通过?是不太可能,还有依赖一部分文件,往下看需要 copy 哪些文件…

4、整合 onvif 服务端框架代码

在第三步生成的源代码的基础上,同时需要 copy gsoap 里面的如下文件到 onvif_code 目录下:

./gsoap-2.8/gsoap/stdsoap2.c
./gsoap-2.8/gsoap/stdsoap2.h
./gsoap-2.8/gsoap/custom/duration.c
./gsoap-2.8/gsoap/custom/duration.h
./gsoap-2.8/gsoap/plugin/wsddapi.c
./gsoap-2.8/gsoap/plugin/wsddapi.h
大概就这些功能,可能有些人还需要调用 http 相关的内容,可以加上相关的文件在,/gsoap-2.8/gsoap/plugin/ 目录下!!!

此时,框架的代码基本生成!到了这一步写一个 Makefile 编译一下你会发现提示很多接口没有实现定义?? what ???
没错,这个接口都是需要自己实现的,而且还是一大推函数接口, 如下截图只是一小部分,后面还有很多…

当时写实现这些接口都写麻了…
在这里插入图片描述
比如我要做 onvif 服务端的,我就对接 soapServer.c 里面所有需要定义没实现的接口,灵动的伙伴们可能到这里开始发现实现接口,参数那些,以及相关结构我怎么知道?
技巧: 你编译提示缺少 XXXXX 函数没实现,你搜索一下会惊讶的发现其实在 soapStub.h 有定义的,所以直接 copy 过来实现就好了!
如下的接口最好重新新建一个文件 onvif_server_interface.c 里面实现
福利福利: github 上的 demo 参考链接:https://github.com/As772309423/onvif-server-discover,里面有实现 onvif_server_interface.c 全部接口
在这里插入图片描述

5、错误说明

把对接 soapServer.c 的接口都实现完了,有些伙伴可能编译通过了,有些可能不行。不通的环境下可能有不一样的错误,我当时在 Ubuntu 下 gcc 下是能编译通过。
最后我换到了 mips 工具链发现,编译出错了、提示了 duration 缺少什么定义,或者类型不对,报错 LONG64 错误等
在 typemap.dat 文件添加如下内容,从新生成代码代码编译即可!

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

在这里插入图片描述
如果前面说的都能顺利通过,那些 onvif 代码框架已经生成了,这只是第一步,后面还需要接着实现 main 函数,以及 soapServer 里面的相关函数接口,还有 wsdl 的裁剪等等!

__wsdd__Probe
__tds__GetDeviceInformation
__tds__GetCapabilities
__tds__GetServices
__trt__GetProfiles
__trt__GetStreamUr
__tds__SetSystemDateAndTime
__trt__GetVideoSources
timg:GetOptions
__tds__GetNetworkInterfaces
__trt__GetOSDs

以上的实现下一篇文章详细说明。

参考链接:
https://www.onvif.org/onvif/ver20/util/operationIndex.html
https://onvif.github.io/specs/doc/index.html
https://github.com/As772309423/onvif-server-discover
https://www.genivia.com/doc/guide/html/index.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值