gsoap 生成 onvif 框架 #
生成参数 #
wsdl2h #
-O4 #
aggressively optimizes the output by “schema slicing” to remove unused schema components, see our article Schema Slicing Methods to Reduce Development Costs of WSDL-Based Web Services for details;
-P #
don’t create polymorphic types inherited from xsd__anyType;
removes the base class xsd__anyType
from the generated C++ classes, which are normally added by wsdl2h if the xsd:anyType
XSD type is used somewhere in a WSDL.
However, for the ONVIF protocols we do not need to inherit the xsd__anyType
class and we can reduce the generated code size accordingly;
-x #
don’t generate _XML any/anyAttribute extensibility elements;
removes the unnecessary generated code for the extensibility elements xsd:any
and attributes xsd:anyAttribue
, since we do not need to support these in general, except for some specific cases see further below. An alternative is to use option -d
to generate embedded DOM code which allows you to add any XML content via the generated xsd__anyType __any
members that are DOM nodes;
wsdl2h 其他参数:
- -h : help
- -s : don’t generate STL code (no std::string and no std::vector)
- -t : typemapfile
soapcpp2 #
-2 #
forces SOAP 1.2, which is required by ONVIF;
-j #
For C++ projects you should generate C++ proxy classes using soapcpp2 option -j
. Proxy classes are** easier to use** than the global functions that are generated without this option.
soapcpp2 其他参数:
- -h: help
- -x : don’t generate sample XML message files
- -d : use path to save files
- -p: save files with new prefix name instead of ‘soap’
- -C: generate client-side source code only
- -L: don’t generate soapClientLib/soapServerLib
- -I : use path(s) for #import (paths separated with ‘:’)
生成过程要做的事情 #
执行前 #
修改 typemap.dat
duration.h 毫秒级 (选了这个)
chrono_duration.h 纳秒级
To automatically enable the first choice of serializer for xsd:duration
, add the following line to typemap.dat
if not already there:
xsd__duration = #``import
"custom/duration.h"
| xsd__duration
This imports custom/duration.h
into the wsdl2h-generated onvif.h
binding interface.
执行 wsdl2h 后 #
change #import "wsdd10.h"
to #import "wsdd5.h"
in onvif.h
You may want to change #import "wsdd10.h"
to #import "wsdd5.h"
in onvif.h
, because ONVIF uses WS-Addressing 2005/08 whereas WS-Discovery declared in wsdd10.h
assumes WS-Addressing 2004/08
添加 #import “wsse.h”
执行 soapcpp2 后 #
Using WS-Security #
-
include
gsoap/plugin/wsseapi.h
-
compile
-
gsoap/plugin/wsseapi.c
-
gsoap/plugin/smdevp.c
-
gsoap/plugin/mecevp.c
-
-DWITH_OPENSSL
and-DWITH_DOM
-
-
link
-lgsoapssl++ 或 compile
gsoap/stdsoap2.cppand
gsoap/dom.cpp\
2.
Using WS-Discovery #
When the ONVIF remotediscovery WSDL is used to build an ONVIF application, WS-Discovery is required.
- include
- gsoap/plugin/wsddapi.h
- compile
- gsoap/plugin/wsddapi.c
To support client-side WS-Discovery operations, we run soapcpp2 as follows as documented here:
soapcpp2 -a -x -L -pwsdd -I ~/gsoap-``2.8``/gsoap/``import
~/gsoap-``2.8``/gsoap/``import``/wsdd5.h
This generates wsddClient.cpp, which we will use later to compile with the project.
编译参数 #
makefile
CC = g++
CPPFLAG = -Wall -g -std=c++11 -w -fPIC -DWITH_NONAMESPACES -fno-use-cxa-atexit -fexceptions -DWITH_DOM -DWITH_OPENSSL -DSOAP_DEBUG
BASE_DIR = .
INCLUDE += -I$(BASE_DIR) -I$(BASE_DIR)/onvif -I$(BASE_DIR)/gsoap -I/usr/local/opt/[email protected]/include
LIB = -lssl -lcrypto -L/usr/local/opt/[email protected]/lib
GsoapSOURCE = $(BASE_DIR)/gsoap
GsoapOBJ = $(GsoapSOURCE)/wsaapi.o $(GsoapSOURCE)/wsseapi.o $(GsoapSOURCE)/threads.o $(GsoapSOURCE)/duration.o \
$(GsoapSOURCE)/smdevp.o $(GsoapSOURCE)/mecevp.o $(GsoapSOURCE)/dom.o $(GsoapSOURCE)/struct_timeval.o
OnvifSOURCE = $(BASE_DIR)/onvif
OnvifOBJ = $(OnvifSOURCE)/soapAdvancedSecurityServiceBindingProxy.o $(OnvifSOURCE)/soapDeviceBindingProxy.o $(OnvifSOURCE)/soapDeviceIOBindingProxy.o \
$(OnvifSOURCE)/soapImagingBindingProxy.o $(OnvifSOURCE)/soapMediaBindingProxy.o $(OnvifSOURCE)/soapPTZBindingProxy.o \
$(OnvifSOURCE)/soapPullPointSubscriptionBindingProxy.o $(OnvifSOURCE)/soapRemoteDiscoveryBindingProxy.o
SRC = $(GsoapSOURCE)/stdsoap2.o $(OnvifSOURCE)/soapC.o $(OnvifSOURCE)/wsddClient.o $(BASE_DIR)/main.o $(GsoapOBJ) $(OnvifOBJ)
OBJECTS = $(patsubst %.cpp,%.o,$(SRC))
TARGET = starry-eyes
all: $(TARGET)
$(TARGET):$(OBJECTS)
$(CC) $(CPPFLAG) $(OBJECTS) $(INCLUDE) $(LIB) -o $(TARGET)
$(OBJECTS):%.o : %.cpp
$(CC) -c $(CPPFLAG) $(INCLUDE) $< -o $@
clean:
rm -rf $(OBJECTS)
遇到的主要问题是这个错误:
Undefined symbols for architecture x86_64:
"soap_s2xsd__dateTime(soap*, char const*, timeval*)", referenced from:
soap_in_saml2__AuthnStatementType(soap*, char const*, saml2__AuthnStatementType*, char const*) in soapC.o
soap_in_saml2__ConditionsType(soap*, char const*, saml2__ConditionsType*, char const*) in soapC.o
soap_in_saml2__SubjectConfirmationDataType(soap*, char const*, saml2__SubjectConfirmationDataType*, char const*) in soapC.o
soap_in_saml2__AssertionType(soap*, char const*, saml2__AssertionType*, char const*) in soapC.o
soap_in_saml1__AuthenticationStatementType(soap*, char const*, saml1__AuthenticationStatementType*, char const*) in soapC.o
soap_in_saml1__ConditionsType(soap*, char const*, saml1__ConditionsType*, char const*) in soapC.o
soap_in_saml1__AssertionType(soap*, char const*, saml1__AssertionType*, char const*) in soapC.o
...
soap_s2xsd__dateTime
这个函数在框架生成的 soapC.cpp 中有多次调用,之前 onvif wsdl 生成的框架里是没有的。
后面找到是 gsoap 的 struct_timeval.c 中实现的,加入编译后,问题解决。
参考:https://www.genivia.com/examples/onvif/index.html
生成过程详情 #
1. 修改 typemap.dat,取消注释
xsdduration = #import “custom/duration.h” | xsdduration
2. 执行 wsdl2h 生成 onvif.h
wsdl2h -O4 -P -x -o onvif.h \
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/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/ptz/wsdl/ptz.wsdl \
http://www.onvif.org/onvif/ver10/network/wsdl/remotediscovery.wsdl \
http://www.onvif.org/ver10/advancedsecurity/wsdl/advancedsecurity.wsdl
3. 修改 onvif.h,change #import "wsdd10.h"
to #import "wsdd5.h
4. 修改 onvif.h,添加 #import “wsse.h”
5. 执行 soapcpp2 生成框架代码
6. 执行 soapcpp2 -pwsdd 生成 wsddClient.cpp
soapcpp2 -2 -C -j -x -I ~/code/onvif/app-gsoap-2.8.98/gsoap:~/code/onvif/app-gsoap-2.8.98/gsoap/import:~/code/onvif/app-gsoap-2.8.98/gsoap/custom onvif.h -d onvif/
soapcpp2 -a -x -L -pwsdd -I ~/code/onvif/app-gsoap-2.8.98/gsoap/import ~/code/onvif/app-gsoap-2.8.98/gsoap/import/wsdd5.h -d onvif/
叶王 © 2013-2024 版权所有。如果本文档对你有所帮助,可以请作者喝饮料。