使用gSoap规避和修改ONVIF标准类型结构的解析

ONVIF/gSoap依赖关系及问题

  1. ONVIF是一组服务规范,标准参考
  2. gSoap是一套基于实现SOAP通信接口的工具链

即是,当我们需要访问ONVIF的Web Service或实现对ONVIF部分的支持;基于C/C++开发,则需要借助gSoap生成这之间的交互接口调用的代码。

gSoap生成代码

  • wsdl2h

将服务接口描述转换为soapcpp2的转换规则,生成中间头文件。

通常我们前期会选择实现部分服务标准;因此这期间生成的后续多为修改这次生成中间产物.h,而不会一切重新生成。

  • soapcpp2

这次是将中间定义转换为实现代码,以供C/C++使用;基本上此过程生成的产物不作特殊处理。因为生成体积庞大,不利于维护修改;而尽量查问题是查找源头或开发逻辑。

ONVIF开发遇到问题

在ONVIF开发过程中最先最常会遇到的问题就是

  1. 调用失败,解析出错
  2. 遇到soap_dom_element类型

下面就着重看看这两类问题的有效处理方式。

规避服务实际扩展带来的解析报错

针对第一个问题,大部分这类问题都说明服务响应的结构不规范,导致解析失败。(比如我遇到的就是雄迈的IPC,在ODT测试GetCapabilities时失败)

通常服务提供商基本服务是能够保证的,问题主要会出现在其扩展结构中。这就是ONVIF标准定义的xsd__anyType

扩展结构当然一般都是可选字段,此时我们忽略不使用即可(只要不影响我们应用需求),观看gsoap生成代码以及最终修改实践我发现,可选字段我们可以选择忽略,这样恰好就规避掉了这情况带来的解析报错,往往一个调用引发的错误,是会导致应用逻辑的决策。

忽略操作,这时候我需要将soapcpp2中间规则的.h中找到相应结构描述的地方,仔细查看该字段如果是Optional,则注释忽略掉便是。重新用soapcpp2工具处理生成新的代码完成。

将 xsd__anyType修改成指定解析结构

对于这个,最常见的就是我们要处理ONVIF对于Event通知的时候,默认生成的都是soap_dom_element这类型结构,如果类型复杂,我们会很难为,需要好深层的遍历实属刁难。但好在对于Event这类实现也是依据规范来实现的,基本填充的内容都标准结构类型。因此我们只要解析出相应的结构信息就可以方便我程序开发使用。

此处参考ONVIF Event消息解析

 

总之,这样一来我们将更方便更好的使用gsoap协助我们的开发工作,预计下一篇内容会往使用gsoap手动序列化,从而突破只用工具生成庞大量代码。因为生成代码都是规则化可视的,如果窥得其中要领,则非常有利于我们简化依赖和为生成代码瘦身。这对于程序发行使用是非常有利的。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
使用gSOAP生成ONVIF框架代码需要遵循以下步骤: 1. 下载gSOAP工具包并安装到本地。 2. 下载ONVIF设备WSDL文件,例如https://www.onvif.org/ver10/device/wsdl/devicemgmt.wsdl。 3. 使用gSOAP工具包中的wsdl2h工具将WSDL文件转换为头文件。 4. 使用soapcpp2工具生成ONVIF框架代码,例如: ```bash soapcpp2 -Iimport devicemgmt.h ``` 5. 在生成的代码中实现ONVIF设备的具体操作。 以下是在Linux系统中使用gSOAP生成ONVIF框架代码的示例: 1. 下载gSOAP工具包并安装到本地: ```bash wget https://sourceforge.net/projects/gsoap2/files/gSOAP/gsoap_2.8.112.zip unzip gsoap_2.8.112.zip cd gsoap-2.8 ./configure make sudo make install ``` 2. 下载ONVIF设备WSDL文件: ```bash wget https://www.onvif.org/ver10/device/wsdl/devicemgmt.wsdl ``` 3. 使用wsdl2h工具将WSDL文件转换为头文件: ```bash wsdl2h -o onvif.h devicemgmt.wsdl ``` 4. 使用soapcpp2工具生成ONVIF框架代码: ```bash soapcpp2 -Iimport onvif.h ``` 5. 在生成的代码中实现ONVIF设备的具体操作。 在生成的代码中,每个ONVIF操作都有对应的函数,例如`SOAP_FMAC5 int SOAP_FMAC6 __tds__GetDeviceInformation(struct soap* soap, _tds__GetDeviceInformation* tds__GetDeviceInformation, _tds__GetDeviceInformationResponse &tds__GetDeviceInformationResponse)`就是获取设备信息的函数。您可以在这些函数中实现具体的操作。 另外,生成的代码中还有一些辅助函数和结构体,您也可以根据需要使用它们。 例如,以下代码片段演示了如何创建一个SOAP客户端并调用`__tds__GetDeviceInformation`函数: ```c++ #include "soapDeviceBindingProxy.h" const char* endpoint = "http://192.168.1.100/onvif/device_service"; DeviceBindingProxy proxy; proxy.soap_endpoint = endpoint; _tds__GetDeviceInformation tds__GetDeviceInformation; _tds__GetDeviceInformationResponse tds__GetDeviceInformationResponse; proxy.__tds__GetDeviceInformation(&tds__GetDeviceInformation, tds__GetDeviceInformationResponse); // 处理返回值 ``` 在使用时,需要将`endpoint`替换为实际的设备IP地址和ONVIF服务端口号。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值