1 准备
1.1 简介
- ONVIF有很多模块,每个模块对应不同的WSDL文档,可以根据需求编译指定WSDL文档;
- WSDL文档可以通过协议规范,选择相应的wsdl,右键链接另存为(本地编译需要,在线编译不需要);
- gSoap可以将WSDL文档编译生成C/C++源码;
- gSoap工具下载地址:gSoap下载
- gSoap使用指南:https://www.genivia.com/resources.html
1.2 下载
- WSDL文档:链接:https://pan.baidu.com/s/1lpg3A3VmFt6jJ2NzWhEpSg 提取码:w775
- gSoap工具:链接:https://pan.baidu.com/s/13KOEu2cMThQIMRUjvfzuzQ 提取码:cb2m
- ONVIF-C源码:链接:https://pan.baidu.com/s/1CFbjmY9bGmwWemc23jbtFA 提取码:0zcl
- ONVIF-C++源码:链接:https://pan.baidu.com/s/15Iilt-U0WWAy-Ql7zPgmKQ 提取码:gd8f
1.3 安装编译OpenSSL
下载编译OpenSSL
,以便得到开启SSL/TLS的wsdl2h文件
地址:https://www.openssl.org/source/
cd /openssl-1.0.2r
./config
sudo make
sudo make install
1.4 安装编译gSOAP
- 下载编译
gsoap
(下载开源版即可GPLv2 Open Source Edition),地址:http://www.cs.fsu.edu/~engelen/soap.html - 编译生成
wsdl2h
和soapcpp2
(mac和Windows上有编译好的,Linux下需要自己编译wsdl2h):
cd gsoap-2.8
$ ./configure --with-openssl=/usr/local/ssl
$ make
$ make install
- error: invalid conversion from ‘char*’ to ‘int’ [-fpermissive] err = str
找到报错对应函数,加入atoi
将char*
转化为int
- 查看是否编译成功
wsdl2h -h # check if successful
whereis soapcpp2 # 查询wsdl2h文件位置
2 编译
- 可以采用本地配置(需改文件,比较麻烦)或者在线配置(需联网)
/usr/local/bin/wsdl2h -h
:可以查看各选项含义/usr/local/bin/soapcpp2 -h
:查看各选项含义- wsdl2h和soapcpp2编译后,可以通过
sudo find / -name wsdl2h
来查找 - 主要分为三个脚本:
wsdl2hOnvif_online.sh
/wsdl2hOnvif_offline.sh
、soapcpp2Onvif.sh
和cp_other_file.sh
在线配置
- 编写脚本
wsdl2hOnvif_online.sh
- C++:
#!/bin/bash
/usr/local/bin/wsdl2h -P -s -x -c++ -t /home/gsoap-2.8/gsoap/typemap.dat -o /home/nvidia/Downloads/ONVIF-C++/onvif.h \
https://www.onvif.org/ver10/device/wsdl/devicemgmt.wsdl\
https://www.onvif.org/ver20/imaging/wsdl/imaging.wsdl\
https://www.onvif.org/ver10/media/wsdl/media.wsdl\
https://www.onvif.org/ver20/media/wsdl/media.wsdl\
https://www.onvif.org/ver20/ptz/wsdl/ptz.wsdl
- C:
#!/bin/bash
/usr/local/bin/wsdl2h -P -x -c -s -t /home/gsoap-2.8/gsoap/typemap.dat -o /home/nvidia/Downloads/ONVIF-C/onvif.h \
https://www.onvif.org/ver10/device/wsdl/devicemgmt.wsdl\
https://www.onvif.org/ver20/imaging/wsdl/imaging.wsdl\
https://www.onvif.org/ver10/media/wsdl/media.wsdl\
https://www.onvif.org/ver20/media/wsdl/media.wsdl\
https://www.onvif.org/ver20/ptz/wsdl/ptz.wsdl
-P
:不要创建继承自xsd__anyType的多态类型
-x
:不要生成_XML任意/anyAttribute可扩展元素
-s
:不要生成STL代码(没有std::string和没有std::vector),
- 鉴权(
onvif.h
开头加入以下)
#import "wsse.h"
- 修改
gsoap/import/wsa5.h
中的SOAP_ENV__Fault
为SOAP_ENV__Fault_WSA5
#import "wsdd10.h" // wsdd10.h中又#import "wsa.h"
#import "wsa5.h" // wsa.h和wsa5.h两个文件重复定义了int SOAP_ENV__Fault
- 编写脚本
soapcpp2Onvif.sh
,生成cpp
代码和链接模块
- C++
#!/bin/bash
/usr/local/bin/soapcpp2 -2 -x -L -C -c++ -d /home/nvidia/ONVIF-C++/build \
-I /home/gsoap-2.8/gsoap \
-I /home/gsoap-2.8/gsoap/import \
-I /home/gsoap-2.8/gsoap/custom \
/home/nvidia/ONVIF-C++/onvif.h
- C:
#!/bin/bash
/usr/local/bin/soapcpp2 -2 -x -L -C -c -d /home/nvidia/ONVIF-C/build\
-I /home/gsoap-2.8/gsoap \
-I /home/gsoap-2.8/gsoap/import \
-I /home/gsoap-2.8/gsoap/custom \
/home/nvidia/ONVIF-C++/onvif.h
-
生成的文件,保留
.c/.cpp
和.h
文件,任选一个.nsmap
,所有.nsmap
文件都是一样的命名空间 -
编写脚本
cp_other_file.sh
,copy其他有用代码
cd /home/gsoap-2.8/gsoap
sudo cp stdsoap2.cpp stdsoap2.h dom.cpp plugin/wsaapi.c plugin/wsaapi.h plugin/wsseapi.cpp plugin/wsseapi.h plugin/mecevp.c plugin/mecevp.h plugin/smdevp.c plugin/smdevp.h plugin/threads.c plugin/threads.h custom/duration.c custom/duration.h custom/struct_timeval.c custom/struct_timeval.h \
/home/nvidia/ONVIF-C++
本地配置
- 在官网https://www.onvif.org/profiles/specifications/,把Service definitions对应下的所有WSDl文件右键保存wsdl文件;
- 编写脚本
wsdl2hOnvif_offline.sh
#!/bin/bash
/usr/local/gSOAP/bin/wsdl2h -c++ -s -t typemap.dat -o samples/onvif/onvif.h \
samples/onvif/wsdl/devicemgmt.wsdl \
samples/onvif/wsdl/event.wsdl \
samples/onvif/wsdl/accesscontrol.wsdl \
samples/onvif/wsdl/accessrules.wsdl \
samples/onvif/wsdl/actionengine.wsdl \
samples/onvif/wsdl/analytics.wsdl \
samples/onvif/wsdl/appmgmt.wsdl \
samples/onvif/wsdl/authenticationbehavior.wsdl \
samples/onvif/wsdl/credential.wsdl \
samples/onvif/wsdl/deviceio.wsdl \
samples/onvif/wsdl/display.wsdl \
samples/onvif/wsdl/doorcontrol.wsdl \
samples/onvif/wsdl/imaging.wsdl \
samples/onvif/wsdl/media.wsdl \
samples/onvif/wsdl/media.wsdl \
samples/onvif/wsdl/provisioning.wsdl \
samples/onvif/wsdl/ptz.wsdl \
samples/onvif/wsdl/receiver.wsdl \
samples/onvif/wsdl/recording.wsdl \
samples/onvif/wsdl/search.wsdl \
samples/onvif/wsdl/replay.wsdl \
samples/onvif/wsdl/schedule.wsdl \
samples/onvif/wsdl/advancedsecurity.wsdl \
samples/onvif/wsdl/thermal.wsdl \
samples/onvif/wsdl/uplink.wsdl
- 编译时由于路径问题可能导致编译失败,修改对应路径即可,编译成功后会自动生成一个
onvif.h
文件。
- 其余和在线配置步骤一致
3 简单测试
main
:
#include <soapH.h>
#include <soapStub.h>
#include <wsseapi.h>
#include "PTZBinding.nsmap"
int main(){
struct soap *soap = NULL;
soap = soap_new();
return 0;
}
Makefile
:
TARGET := testPTZ
SOURCE := $(wildcard ../src/*.c) $(wildcard ../src/*.cpp) $(wildcard ../third/ONVIF-C++/src/*.cpp) $(wildcard ../third/ONVIF-C++/src/*.c)
OBJS := $(patsubst %.cpp,%.o,$(patsubst %.c,%.o, $(SOURCE)))
CXX := g++
LIBS = /usr/local/lib/libssl.a\
/usr/local/lib/libcrypto.a
LIBS += -lpthread -ldl
LDFLAGS :=
DEFINES := -DWITH_OPENSSL -DWITH_DOM -DWITH_NONAMESPACES
INCLUDE := -I/usr/include\
-I../third/ONVIF-C++/include\
-I/usr/local/include/openssl
CFLAGS = -g -Wall -O3 $(DEFINES) $(INCLUDE) -fPIC
CXXFLAGS:= $(CFLAGS) -std=c++11 -Wunused-function -Wunused-variable -Wfatal-errors
.PHONY : everything objs clean veryclean rebuild
everything : $(TARGET)
all : $(TARGET)
rebuild: veryclean everything
clean :
rm -fr ../src/*.so
rm -fr ../src/*.o
veryclean : clean
rm -fr $(TARGET)
%.o : %.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
%.o : %.c
$(CXX) -c $(CXXFLAGS) $< -o $@
$(TARGET) : $(OBJS)
$(CXX) $(CXXFLAGS) -o $@ $(OBJS) $(LDFLAGS) $(LIBS)