当前位置: 首页 > 流媒体学习 > 正文

onvif学习笔记4:Windows环境使用gsoap生成onvif框架代码

因工作原因,被安排接手onvif,为了对其有个真正、切实、系统、认真、严谨的了解,就利用周末等业余时间来学习研究。
本文主要讲述在windows环境中使用gsoap生成onvif框架的代码,但不涉及框架代码的使用。由于实际真正使用的只有生成的代码文件,所以无论使用Linux还是Windows,都无所谓。
一、下载gsoap工具
gsoap下载地址为:https://sourceforge.net/projects/gsoap2/files/gSOAP/,截至本文编写时,最新版本为2.8.29,发布时间为2月24日。生成代码所需的wsdl2h.exe和soapcpp2.exe工具在gsoap\bin\win32目录。
二、生成onvif.h头文件
1、
wsdl2h是利用webservice描述语言(wsdl)生成头文件,下面的命令语句是将onvif官网上提供wsdl生成onvif.h头文件。注意typemap.dat为gsoap源码自带的文件。

wsdl2h.exe -t ../gsoap/typemap.dat -o onvif.h -d \
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

(如果使用dos命令提示符,请把“\”去掉,使用mingw环境无须如此)
2、
生成的onvif.h文件中,在#import “wsa5.h”后面添加#import “wsse.h”,引入wsse.h头文件。
3、将gsoap源码的was5.h(位于gsoap\import目录)的SOAP_ENV__Fault函数改名如下:

int SOAP_ENV__Fault_LateLee
(       _QName faultcode,// SOAP 1.1
        char *faultstring,// SOAP 1.1
        char *faultactor,// SOAP 1.1
        struct SOAP_ENV__Detail *detail,// SOAP 1.1
        struct SOAP_ENV__Code *SOAP_ENV__Code,// SOAP 1.2
        struct SOAP_ENV__Reason *SOAP_ENV__Reason,// SOAP 1.2
        char *SOAP_ENV__Node,// SOAP 1.2
        char *SOAP_ENV__Role,// SOAP 1.2
        struct SOAP_ENV__Detail *SOAP_ENV__Detail,// SOAP 1.2
void
);

如果不修改,则会出现重定义错误,如下:

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

三、由onvif.h生成框架代码
命令如下:

soapcpp2.exe -i -S -I ../gsoap/import/ -I ../gsoap/ onvif.h

注:soapcpp2有许多参数,可用soapcpp2 -h查看。其中-c表示生成c格式代码(注:后缀名还是.cpp,但实现上是C),-c++表示生成c++格式代码(默认)。-x表示不产生xml文件(注:生成的xml可指导后续的开发工作,建议不使用“-x”参数)。-i表示生成代码的类继承soap结构体,-j表示类内部引用soap结构体。-I表示指定导入文件路径。-S表示生成服务端代码(文件名为xxxService.cpp),-C表示生成客户端代码(文件名为xxxProxy.cpp)。
上述命令表示生成C++代码,只产生服务端代码,使用继承soap的形式。另外生成xml文件。
四、生成代码简析
*.nsmap的文件为Namespace的定义,所有该后缀的文件内容是一样的。建议保留一份,并重新命名为namespace.h,这样更适合C++代码传统。值得注意的是,在生成框架的文件中,在需要使用命名空间,会在函数中定义和*.nsmap中内容一致的的结构体,而不是引用*.nsmap。这点在实际工作也可以参考。
soapXXXProxy.h/.cpp为client端代码文件。头文件类示例如下:

    class SOAP_CMAC DeviceBindingProxy : public soap {
      public:
        /// Endpoint URL of service 'DeviceBindingProxy' (change as needed)
        const char *soap_endpoint;
        /// Variables globally declared in onvif.h, if any
        /// Construct a proxy with new managing context
        DeviceBindingProxy();
        /// Copy constructor
        DeviceBindingProxy(const DeviceBindingProxy& rhs);
        /// Construct proxy given a managing context
        DeviceBindingProxy(const struct soap&);
        /// Constructor taking an endpoint URL
        DeviceBindingProxy(const char *endpoint);
        /// Constructor taking input and output mode flags for the new managing context
        DeviceBindingProxy(soap_mode iomode);
        /// Constructor taking endpoint URL and input and output mode flags for the new managing context
        DeviceBindingProxy(const char *endpoint, soap_mode iomode);
        /// Constructor taking input and output mode flags for the new managing context
        DeviceBindingProxy(soap_mode imode, soap_mode omode);
        /// Destructor deletes deserialized data and managing context
        virtual ~DeviceBindingProxy();
        }

soapxxxService.h/.cpp为server端代码文件。头文件类示例如下:

    class SOAP_CMAC DeviceBindingService : public soap {
      public:
        /// Variables globally declared in onvif.h, if any
        /// Construct a service with new managing context
        DeviceBindingService();
        /// Copy constructor
        DeviceBindingService(const DeviceBindingService&);
        /// Construct service given a managing context
        DeviceBindingService(const struct soap&);
        /// Constructor taking input+output mode flags for the new managing context
        DeviceBindingService(soap_mode iomode);
        /// Constructor taking input and output mode flags for the new managing context
        DeviceBindingService(soap_mode imode, soap_mode omode);
        /// Destructor deletes deserialized data and managing context
        virtual ~DeviceBindingService();
        /// Delete all deserialized data (with soap_destroy() and soap_end())
        virtual void destroy();
        /// Delete all deserialized data and reset to defaults
        virtual void reset();
        }

*.xml为xml命令协议格式文件,在调试时可做参考,下面为SetNTP命令的xml格式,注意,onvif的xml字符编码为UTF-8。

 <SOAP-ENV:Header>
 </SOAP-ENV:Header>
 <SOAP-ENV:Body>
   <tds:SetNTP>
    <tds:FromDHCP>false</tds:FromDHCP>
    <tds:NTPManual>
     <tt:Type>IPv4</tt:Type>
     <tt:IPv4Address></tt:IPv4Address>
     <tt:IPv6Address></tt:IPv6Address>
     <tt:DNSname></tt:DNSname>
     <tt:Extension>


     </tt:Extension>
    </tds:NTPManual>
   </tds:SetNTP>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

根据本文命令生成的代码参见github仓库:https://github.com/latelee/onvif_fw_stl.git
李迟 2016.3.5 周六 时值两会,听政府工作报告

本文固定链接: http://www.latelee.org/multistream/onvif-note4-gsoap-generate-under-windows.html

目前暂无评论

发表评论

*

快捷键:Ctrl+Enter