gsoap生成onvif c/c++代码框架

1. 到官网下载gsoap源码

下载地址:https://sourceforge.net/projects/gsoap2/
我当前下载的版本是gsoap_2.8.134

2. 编译gsoap

编译环境:Ubuntu18.04

  • 解压
unzip gsoap_2.8.134.zip
  • 配置
cd gsoap_2.8.134
mkdir install
./configure --prefix=/home/james/workdir/gsoap-2.8/install
prefix替换为自己的安装路径
  • 编译安装
make && make install

3. 生成的工具

进入/home/james/workdir/gsoap-2.8/install/bin目录下,里面就是生成的工具了
在这里插入图片描述
wsdl2h的作用是根据WSDL文件生成一个gsoap用到的头文件,wsdl2h 常用指令:

  • -o filename.h   将wsdl转化为filename.h头文件。
  • -s         不生成STL代码
  • -c         生成纯C风格的头文件,这将去除C++的一些特性
  • -n name      使用name代替默认前缀ns
  • -t filename.dat  使用filename.dat代替默认的typemap.dat文件
  • -zX        兼容之前的X版本

soapcpp2的作用是根据头文件自动生成调用远程 SOAP服务的客户端代码(称为存根:Stub)和提供SOAP服务的框架代码(称为框架:Skeleton),另外它也能从头文件生成WSDL文件。其中,soapH.h and soapC.c包含了数据类型的描述,soapClient.c给客户端使用,soapServer.c给服务端使用。

  • -i     生成server的proxy和object,这种object继承于soap struct。

  • -j     和-i类似,区别在于生成的代理类不继承于soap struct,而是包含了包含了一个soap结构的指针。此种方式生存的代理类便于互相通信

  • -C    仅生成客户端client代码

  • -S    仅生成服务端server代码

  • -x    不生成xml文件。不用此项的话,将对头文件中定义的每个operation生成一个描述性的xml文件

  • -L    不生成soapClientLib文件和soapServerLib文件

  • -p name 修改文件名前缀,代替soap

  • -q name 指定代理类和对象使用的名空间name,包含文件名前缀

  • 编译问题
    (1)缺少autoconf

(CDPATH="${ZSH_VERSION+.}:" && cd . && /bin/bash '/home/james/workdir/gsoap-2.8/missing' autoheader)
/home/james/workdir/gsoap-2.8/missing: line 81: autoheader: command not found

解决:

sudo apt install autoconf

(2)缺少openssl

In file included from stdsoap2_ssl.c:75:0:
stdsoap2.h:903:11: fatal error: openssl/bio.h: No such file or directory
 # include <openssl/bio.h>

解决:

sudo apt-get install libssl-dev

(3)缺少zlib

In file included from stdsoap2_ssl.c:75:0:
stdsoap2.h:956:11: fatal error: zlib.h: No such file or directory
 # include <zlib.h>

解决:

sudo apt install zlib1g-dev

(4)使用生成的duration.c时,LONG64报错在这里插入图片描述
解决:

onvif_code目录下
vim ../../gsoap/typemap.dat
取消下面这行代码的注释
xsd__duration = #import "custom/duration.h" | xsd__duration

4. 生成onvif c/c++框架代码

(1)准备好WSDL文件
WSDL官网网址:点击这里WSDL文件地址
地址:https://www.onvif.org/profiles/specifications/
可以选择需要的wsdl文件下载,或者直接使用对应的https网址

(2)使用wsdl2h生成onvif.h头文件

  • 执行以下步骤生成头文件
    onvif_code是自定义目录,用于存放生成的onvif.h和后续的.c文件
cd /home/james/workdir/gsoap-2.8/install
mkdir onvif_code
cd onvif_code
mkdir onvif
mkdir onvif_soap

直接使用https网址的wsdl生成onvif.h头文件

../bin/wsdl2h -c -x -t ../../gsoap/typemap.dat -o onvif/onvif.h \
   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

使用下载好的wsdl生成

../bin/wsdl2h -c -x -t ../../gsoap/typemap.dat -o onvif/onvif.h ../wsdl/remotediscovery.wsdl ../wsdl/devicemgmt.wsdl ../wsdl/media.wsdl ../wsdl/media2.wsdl ../wsdl/imaging.wsdl ../wsdl/ptz.wsdl

现在可以看到生成的onvif.h在onvif_code/onvif目录下
在这里插入图片描述

  • 修改onvif.h,支持鉴权,即可以使用soap_wsse_add_UsernameTokenDigest等鉴权相关的函数
    增加#import “wsse.h”
    在这里插入图片描述
  • 修改import/wsa5.h文件
vim ../../gsoap/import/wsa5.h
找到int SOAP_ENV__Fault结构体定义,将名字改为int SOAP_ENV__Fault_XXX以避免冲突,保存退出编辑

(3)使用soap2cpp生成c/c++客户端代码文件
生成的文件在onvif目录下

../bin/soapcpp2 -2 -x -C onvif/onvif.h  -L -I ../../gsoap/import -I ../../gsoap/ -donvif

在onvif_code/onvif目录下生成了客户端代码
在这里插入图片描述
留下wsdd.nsmap文件,其他的nsmap文件内容都是一样的,删除掉即可。
在这里插入图片描述
拷贝需要的源文件到onvif_code/onvif_soap目录
编写脚本copy.sh

#!/bin/sh

cd /home/james/workdir/gsoap-2.8
cp gsoap/stdsoap2.c gsoap/stdsoap2.h gsoap/plugin/wsaapi.c gsoap/plugin/wsaapi.h gsoap/custom/duration.c gsoap/custom/duration.h install/onvif_code/onvif_soap
cp gsoap/custom/struct_timeval.* install/onvif_code/onvif_soap
# 用于授权验证的一些文件
cp gsoap/dom.c gsoap/plugin/mecevp.* gsoap/plugin/smdevp.* gsoap/plugin/threads.* gsoap/plugin/wsseapi.* install/onvif_code/onvif_soap

执行copy.sh后,此时的onvif_code/onvif_soap目录的文件如下
在这里插入图片描述

到这里,onvif客户端的代码框架就生成了。

(4)编译成库
在onvif_code目录下新建CMakeLists.txt

cmake_minimum_required(VERSION 3.0)
project(ONVIF_SOAP_LIB)
set(CMAKE_C_COMPILER "gcc")
set(CMAKE_CXX_FLAGS "-g -O0")

set(LIB_SOAP_SRC
    onvif_soap/struct_timeval.c
    onvif_soap/duration.c
    onvif_soap/wsaapi.c
    onvif_soap/dom.c
    onvif_soap/wsseapi.c
    onvif_soap/smdevp.c
    onvif_soap/mecevp.c
    onvif_soap/threads.c
    onvif_soap/stdsoap2.c)

add_library(onvif_soap STATIC ${LIB_SOAP_SRC})
target_link_libraries(onvif_soap PUBLIC ssl crypto)
target_compile_definitions(onvif_soap PUBLIC WITH_OPENSSL WITH_DOM)
target_include_directories(onvif_soap PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/onvif ${CMAKE_CURRENT_SOURCE_DIR}/onvif_soap)

add_library(onvif STATIC onvif/soapC.c onvif/soapClient.c)
target_include_directories(onvif PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/onvif)
target_link_libraries(onvif PUBLIC onvif_soap)

执行以下命令生成库

mkdir build
cd build
cmake ..
make

后续就可以通过库的方式进行使用。

THE END!
参考链接:
https://blog.csdn.net/noevil/article/details/133084718

使用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、付费专栏及课程。

余额充值