c++ onvif客户端开发番外:windows上编译gsoap并导入Qt工程

9 篇文章 0 订阅

我本来是打算写一系列Linux c++ onvif客户端开发系列文章,详见:

 下载安装openssl

Win32/Win64 OpenSSL Installer for Windows - Shining Light Productions (slproweb.com)

下载已经编译好的openssl并安装,注意要下载完整版——包含头文件和库文件的版本。

这里给一个直接下载链接https://slproweb.com/download/Win64OpenSSL-3_2_1.exe

openssl是为了编译wsdl2h.exe。

下载gSOAP源码

gSoap分商业版和开源版本,开源版可以从gSOAP Toolkit download | SourceForge.net下载

gsoap工具可以根据wsdl接口文档生成onvif源码,必须用到wsdl2h和soapcpp2两个工具(执行文件)。

我这里下载的gsoap_2.8.132 版本,并解压备用。

编译支持https下载的wsdl2h.exe

gsoap_2.8.132\gsoap-2.8\gsoap\bin\win64目录下已经提供了编译好的两个可执行文件。

但是这个windows版本wsdl2h.exe默认不支持HTTPS下载。也就是说无法使用这样的命令生成接口头文件。

wsdl2h -c++11 -x -t gsoap/typemap.dat https://www.onvif.org/ver10/device/wsdl/devicemgmt.wsdl

这一步还是很繁琐的。

 VS2019迁移wsdl2h工程

使用VS2019 打开gsoap_2.8.132\gsoap-2.8\gsoap\VisualStudio2005\wsdl2h\wsdl2h.sln,并接受升级。

迁移完成之后会有个报告,只要没有错误也就可以继续操作了。

增加x64编译配置

新建release方案选择x64新平台,并从win32创建

完成之后关闭窗口

配置编译选项包含openssl

解决方案资源管理器中,在wsdl2h项目上右键,选中“属性”,弹出项目属性编辑对话框。

先添加头文件包含目录,在C/C++附加包含目录中直接填入

C:\Program Files\OpenSSL-Win64\include

 确认C++代码库运行方式,为MT,不用修改

链接器附加库目录填写

C:\Program Files\OpenSSL-Win64\lib\VC\x64\MT

这里要和上面的C++运行库方式要匹配。这里知识点

  • /MTmultithread-static version,是多线程静态版本的意思,项目会使用运行时库的多线程静态版本,编译器会将LIBCMT.lib放入.obj文件中,以便链接器使用LIBCMT.lib解析外部符号;
  • /MTd是定义了_DEBUG/MT,是/MT类型的debug版本;
  • /MDmultithread-dll version,是多线程dll版本的意思,项目会使用运行时库的多线程动态dll版本,编译器会将MSVCRT.lib放入.obj文件中,在编译项目时,它会静态链接MSVCRT.lib,但在实际运行过程中,它会链接使用MSVCR90.dll
  • MDd是定义了_DEBUG/MD,是/MD类型的debug版本;

附加依赖项增加

;libcrypto.lib;libssl.lib 

可以自己打开去按行填写,也可以直接编辑,使用;分割即可。 

 预处理器增加WITH_OPENSSL

然后配置完毕,应用、保存。

复制httpda.h/httpda.c到wsdl2h源码目录

gsoap_2.8.132\gsoap-2.8\gsoap\plugin\httpda.c 

gsoap_2.8.132\gsoap-2.8\gsoap\plugin\httpda.h

gsoap_2.8.132\gsoap-2.8\gsoap\plugin\smdevp.c

gsoap_2.8.132\gsoap-2.8\gsoap\plugin\smdevp.h

gsoap_2.8.132\gsoap-2.8\gsoap\plugin\threads.c

gsoap_2.8.132\gsoap-2.8\gsoap\plugin\threads.h

将上面两个文件复制到

gsoap_2.8.132\gsoap-2.8\gsoap\VisualStudio2005\wsdl2h\wsdl2h 

并加入项目源文件中

重新生成

即可编译成功gsoap_2.8.132\gsoap-2.8\gsoap\VisualStudio2005\wsdl2h\x64\Release\wsdl2h.exe

创建目录结构并复制文件

创建libonvif目录,下面再创建4个子目录,子目录的用处如下

├── gsoap   从gsoap-2.8源代码中复制的一些文件,只有typemap.data 做了修改,这些编译时候其实用不到,但是可以放在这里
│   ├── custom
│   ├── import
│   └── plugin
├── onvif 生成的文件,需要编译进来
├── onvif_head 生成的一个中间头文件,可以删除
├── soap  从gsoap中复制的一些文件,后续需要编译进来

复制gosap源码

将gsoap_2.8.132\gsoap-2.8\gsoap 目录下的以下目录和文件复制到新建目录下的libonvif/gsoap目录下

custom/

extras/

import/

plugin/

dom.cpp

stdsoap2.cpp

stdsoap2.h

typemap.dat

复制wsdl2h和soapcpp2到libonvif目录

gsoap_2.8.132\gsoap-2.8\gsoap\VisualStudio2005\wsdl2h\x64\Release\wsdl2h.exe

这个是自己编译的支持https下载的工具

gsoap_2.8.132\gsoap-2.8\gsoap\bin\win64\soapcpp2.exe 这是源码包自带的工具

修改gsoap/typemap.dat

xsd__duration = #import “custom/duration.h” | xsd__duration

生成接口文件onvif_head/onvif.h

使用的相关wsdl文件描述 按需求自己变更
- 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/ver10/media/wsdl/media.wsdl 获取264的视频流地址
- https://www.onvif.org/onvif/ver20/media/wsdl/media.wsdl 获取h265视频流地址
- http://www.onvif.org/onvif/ver20/imaging/wsdl/imaging.wsdl 光圈,对比度,饱和度

如下内容保存为libonvif/step1_gen.bat

@echo off

set WSDL2H_BIN=wsdl2h.exe

set DST=onvif_head\onvif.h

%WSDL2H_BIN% -c++11 -x -t gsoap\typemap.dat -o %DST%  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

:: # https://www.onvif.org/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/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

然后双击运行

 生成源码

增加鉴权头文件

鉴权也就是设备使用用户名密码登录。

如果onvif.h不加入#import "wsse.h",使用soap_wsse_add_UsernameTokenDigest函数会导致编译出错,也就无法登录设备进行操作了。

但是默认生成的onvif.h中是没有#import "wsse.h"的。

手动在onvif_head/onvif.h  122行增加

#import "wsse.h"   // 这里是新增的一行

#import "wsdd10.h"  // wsdd10 = <http://schemas.xmlsoap.org/ws/2005/04/discovery>

#import "xop.h" // xop = <http://www.w3.org/2004/08/xop/include>

#import "wsa5.h"    // wsa5 = <http://www.w3.org/2005/08/addressing>

SOAP_ENV__Fault重复定义

如果没有修改相关文件,生成代码的时候会出现如下错误。

wsa5.h(280): *WARNING*: Duplicate declaration of 'SOAP_ENV__Fault' (already declared at line 268)

wsa5.h(290): **ERROR**: service operation name clash: struct/class 'SOAP_ENV__Fault' already declared at wsa.h:278

之所有会出现这个错误,是因为onvif.h头文件中同时:

 #import "wsdd10.h" // wsdd10.h中又#import "wsa.h"

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

 解决方法:

修改libonvif\gsoap\import\wsa5.h文件,将int SOAP_ENV__Fault修改为不冲突的任何名字,例如int SOAP_ENV__Fault_xxx,再次使用soapcpp2工具编译就成功了。

生成

如下保存为libonvif\step2_gen_cpp.bat

@REM @echo off

set SOAPCPP_BIN=soapcpp2.exe

%SOAPCPP_BIN% -2 -c++11 -C -L -x -I gsoap;gsoap/import;gosap/custom -d onvif onvif_head/onvif.h

:: 拷贝其他还有会用的源码

copy gsoap\stdsoap2.cpp soap

copy gsoap\stdsoap2.h soap

copy gsoap\plugin\wsaapi.h soap  

copy gsoap\plugin\wsaapi.c soap\wsaapi.cpp  

copy gsoap\custom\duration.c soap\duration.cpp

copy gsoap\custom\duration.h soap

copy gsoap\custom\struct_timeval.h soap  

copy gsoap\custom\struct_timeval.c soap\struct_timeval.cpp

@REM ::  用于授权验证的一些文件

copy gsoap\dom.cpp soap

copy gsoap\plugin\mecevp.h soap  

copy gsoap\plugin\mecevp.c soap\mecevp.cpp

copy gsoap\plugin\smdevp.h soap

copy gsoap\plugin\smdevp.c soap\smdevp.cpp  

copy gsoap\plugin\threads.h soap  

copy gsoap\plugin\threads.c soap\threads.cpp

copy gsoap\plugin\wsseapi.h soap

copy gsoap\plugin\wsseapi.c soap\wsseapi.cpp

@REM ::  删除多余nsmap——都一样,冗余了

@REM mv onvif/wsdd.nsmap onvif/wsdd.nsmap.bak

@REM rm onvif/*.nsmap

@REM mv onvif/wsdd.nsmap.bak onvif/wsdd.nsmap

pause

双击运行

生成文件如下

Qt导入onvif库 及demo

创建libonvif\onvif.pri ,你自己的pro文件可以include 这个文件

INCLUDEPATH += $$PWD/onvif \
               $$PWD/soap

INCLUDEPATH += "C:\Program Files\OpenSSL-Win64\include"

DEFINES += WITH_OPENSSL WITH_DOM

win32:QMAKE_CXXFLAGS += /bigobj

HEADERS += \
    $$PWD/onvif.h \
    $$PWD/onvif.h \
    $$PWD/onvif/soapH.h \
    $$PWD/onvif/soapStub.h \
    $$PWD/onvif/wsdd.nsmap \
    $$PWD/soap/duration.h \
    $$PWD/soap/mecevp.h \
    $$PWD/soap/smdevp.h \
    $$PWD/soap/stdsoap2.h \
    $$PWD/soap/struct_timeval.h \
    $$PWD/soap/threads.h \
    $$PWD/soap/wsaapi.h \
    $$PWD/soap/wsseapi.h

SOURCES += \
    $$PWD/namespace.cpp \
    $$PWD/onvif.cpp \
    $$PWD/onvif.cpp \
    $$PWD/onvif/soapClient.cpp \
    $$PWD/onvif/soapC.cpp \
    $$PWD/soap/dom.cpp \
    $$PWD/soap/duration.cpp \
    $$PWD/soap/mecevp.cpp \
    $$PWD/soap/smdevp.cpp \
    $$PWD/soap/stdsoap2.cpp \
    $$PWD/soap/struct_timeval.cpp \
    $$PWD/soap/threads.cpp \
    $$PWD/soap/wsaapi.cpp \
    $$PWD/soap/wsseapi.cpp


LIBS    += "C:\Program Files\OpenSSL-Win64\lib\VC\x64\MT\libssl.lib" \
           "C:\Program Files\OpenSSL-Win64\lib\VC\x64\MT\libcrypto.lib"

Demo及其他的一些帮助文件可以在https://gitee.com/noevilme/bilibili/tree/master/onvif/WinOnvif/libonvif 看到

 里面也有个Demo可以直接编译使用

使用的注意事项 

# winsock库和winsock2库冲突, 需要在pro文件中增加
DEFINES += WIN32_LEAN_AND_MEAN

pri文件使用方式为

INCLUDEPATH += $$PWD/../libonvif
include ($$PWD/../libonvif/onvif.pri) 
  • 18
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值