ONVIF协议网络摄像机(IPC)客户端程序开发使用gSOAP生成ONVIF框架代码(C++)03–>Windows

  • Post author:
  • Post category:其他


其它的不多说,直接开始步骤。

我的版本是2.8.109,目前最新版本。

实际上,onvif的源码是兼容Linux、Windows版本的,例如如果你已经在这篇文章

ONVIF协议网络摄像机(IPC)客户端程序开发使用gSOAP生成ONVIF框架代码(C++,并支持h264、h265)01–>CentOS

编译好了对应的Onvif源码,那么就可以直接使用了,例如你可以使用这份在Linux生成Onvif源码在Windows下生成静态库。



1 gsoap工具下载地址


1)下载


去下面网址按注释下载。

https://sourceforge.net/projects/gsoap2//最新版本,点击Files,然后下载


2)解压


在这里插入图片描述


3)windows与linux不一样,不需要安装相应配置,直接进入对应的目录即可。


进入以下目录。

在这里插入图片描述



2 使用gSOAP生成ONVIF框架代码


2.1 准备原材料


1)在win64创建了一个dev_onvif目录。并且在dev_onvif目录内创建bin,gsoap两个空目录。

2)拷贝wsdl2h.exe,soapcpp2.exe进去刚刚创建的bin目录。

3)将gsoap2.8/gsoap内的custom,extras,import,plugin,WS目录和dom.cpp,stdsoap2.h,stdsoap2.cpp(.c文件不需要处理,因为与同名的cpp是完全一样的)源代码文件拷贝到刚刚创建的gsoap。

所以目前的目录架构是这样的。

win64内部:

在这里插入图片描述

dev_onvif内部:

在这里插入图片描述

gsoap内部:

在这里插入图片描述


2.2 防止出现LONG64的错误


为了不让编译时出现LONG64的错误,我们需要在typemap.dat(在刚刚创建的gsoap/WS)中去掉一个注释,注意,只需要删除一个#即可。大概218行。

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


2.3 生成onvif.h头文件


为了方便,在dev_onvif目录下编写脚本onvif_head.sh,生成头文件。

需要注意的是:由于windows的wsdl2h不支持https协议,所以只能使用http。一开始我直接使用linux的下载方法导致我也浪费了点时间处理。

另外,最下面我给出了所有需要用到的wsdl文件和xsd文件。根据个人而定,网速好的话尽量在线下载好点。

但是,如果没有相关要求,建议最好全都下载,这样后续缺少模块后,不用每次都要重新下载一遍。

例如,获取profile时,需要ver20版本的media.wsdl,若只下载了ver10版本的media.wsdl,则没办法兼容,具体看

ONVIF协议网络摄像机(IPC)客户端程序开发使用gSOAP生成ONVIF框架代码(C++,并支持h264、h265)01–>CentOS

的注释。

#!/bin/bash
#wsdl2h -help查看选项帮助

if [ ! -d "onvif_head" ]; then 
	mkdir onvif_head
else
   rm -rf onvif_head/*
fi

# 注意,这里是进入了onvif_head/目录的,所以下面是../bin/wsdl2。
cd onvif_head/

#有些地址缺少onvif节点是因为加上onvif可能会打不开。例如第三个media,但是有时又行,我试过晚上可能比较慢。甚至突然无法下载。我试过有些是因为不支持https协议导致的,可以试试换成http。
#并且注意:想要开发光圈,对比度,饱和度设置的,需要添加imaging.wsdl,这是我后面加上的.不过不是嵌入式的,建议还是全部下载吧,我后面也是全部下载

#下面是所有的wsdl和xsd(下面只有2个xsd),根据需求添加。在线下载时,xsd可以不管,xsd一般是下载到本地后好像才有用的,具体忘记了。反正在线下载就不会错。

../bin/wsdl2h -x -t ../gsoap/WS/typemap.dat -o onvif.h \
http://www.onvif.org/onvif/ver10/network/wsdl/remotediscovery.wsdl http://www.onvif.org/onvif/ver10/device/wsdl/devicemgmt.wsdl \
http://www.onvif.org/onvif/ver10/events/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/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/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 \
http://www.onvif.org/ver10/pacs/accesscontrol.wsdl http://www.onvif.org/ver10/pacs/doorcontrol.wsdl \
http://www.onvif.org/ver10/advancedsecurity/wsdl/advancedsecurity.wsdl http://www.onvif.org/ver10/accessrules/wsdl/accessrules.wsdl \
http://www.onvif.org/ver10/credential/wsdl/credential.wsdl http://www.onvif.org/ver10/schedule/wsdl/schedule.wsdl \
http://www.onvif.org/ver10/pacs/types.xsd


1.4 因鉴权需要,修改onvif.h头文件


在脚本生成的onvif_head目录内的onvif.h头文件添加下面内容。

#import "wsse.h"


1.5 根据onvif.h生成onvif框架的代码


在onvif_head.sh同路径创建onvif_code.sh,添加如下内容:

#!/bin/bash
if [ ! -d "soap" ]; then 
	mkdir soap
else
   rm -rf soap/*
fi
cd soap
 ../bin/soapcpp2 -2 -x -C ../onvif_head/onvif.h  -L -I ../gsoap/import -I ../gsoap/
#-2表示获取1.2资源代码,-x表示不获取XML信息文件,-C表示只生成客户端代码
#-L表示不生成客户端或者服务端的库,-I表示import导入路径

添加权限后执行脚本。

报错,这是因为这两个文件重定义了。

#import "wsdd10.h" // wsdd10.h中又#import "wsa.h"
#import "wsa5.h"   // wsa.h和wsa5.h两个文件重复定义了int SOAP_ENV__Fault

解决: 将gsoap源码的wsa5.h(位于刚刚创建的gsoap/import目录)的SOAP_ENV__Fault函数改成其他名字或者直接注释掉。

我是改成其它名字。

int SOAP_ENV__Fault修改为int SOAP_ENV__Fault_alex

重新执行脚本即可。


1.6 结果


可以看到,成功生成了onvif.h和相应的客户端代码。

在这里插入图片描述

上面的命名空间都是这样的内容,所以只需要留一个wsdd.nsmap即可。



3 整理代码

1)在soap的同级目录中创建一个ONVIFAPI文件夹,用于存项目开发时使用。

2)拷贝刚刚生成soap目录内的相关源文件到ONVIFAPI。

cp ../soap/soapH.h ../soap/soapStub.h ../soap/soapC.cpp ../soap/soapClient.cpp ../soap/wsdd.nsmap .

3)拷贝plugin里面的源码到ONVIFAPI。

cp ../gsoap/plugin/wsseapi.* ../gsoap/plugin/wsaapi.* ../gsoap/plugin/threads.* ../gsoap/plugin/smdevp.* ../gsoap/plugin/mecevp.* ../gsoap/plugin/md5evp.* .

4)拷贝custom里面的源码到ONVIFAPI。

cp ../gsoap/custom/struct_timeval.* ../gsoap/custom/duration.* .

5)拷贝dom.cpp,stdsoap2.h,stdsoap2.cpp到ONVIFAPI。

cp ../gsoap/dom.cpp ../gsoap/stdsoap2.* .

6)修改.c后缀成.cpp,防止无法编译vector这些C++特有的容器。这里可能你会拷贝多一个wsseapi的.c文件,删除即可。并且同名的.c和.cpp文件是完全一样的,我使用工具对比过了。所以你可以方心的修改后缀即可。我的版本是2.8-109,共24个文件。

在这里插入图片描述

7)关联自己的命名空间,修改stdsoap2.cpp文件,在开头加入下面内容。实际上你也可以在其它地方添加,但是容易重定义命名空间,所以我们到最后编写Onvif的函数时,需要类似模板一样,不要将头文件和.cpp文件分离。

#include “wsdd.nsmap”

在这里插入图片描述

上面就已经完成了整个onvif框架的搭建。然后拷贝到你想要开发的项目即可。实际上过程和linux是极其相似的。



4 注意点总结

  • 1)windows的wsdl2h不支持https协议,在下载wsdl文件时必须使用http协议。
  • 2)如果不想上面利用http在线下载的话,就必须提前将所有(或者个人需要的)的wsdl和所需要的xsd文件下载下来。官网如下:
https://www.onvif.org/profiles/specifications/

可以看到,官网也不是全部都有对应的wsdl,但是xsd文件还有足够我们使用的。如果没有对应的wsdl文件,例如remotediscovery.wsdl就没有,这时我们需要按照我上面所给的网址单独下载下来(还是在线好吧)。或者若wsdl和xsd缺少,我们也可以去typemap.dat所在的目录中查找,最好按照缺少的网址下载,因为typemap.dat所在的目录中并不是每个缺少文件都有。

在这里插入图片描述

  • 3)并且,如果我们是提前下载完在生成onvif的框架的话,在生成onvif,h时,必须将每个wsdl文件的schemaLocation的路径修改成本地存放的路径,而不能再是http网址原来的路径。

    在这里插入图片描述

    改成:

    在这里插入图片描述



版权声明:本文为weixin_44517656原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。