繁体   English   中英

具有ONVIF规范中的多个wsdl的gSOAP服务器

[英]gSOAP server with multiple wsdl from ONVIF specifications

我正在尝试使用gSOAP在C ++中创建Web服务。 我从ONVIF wsdl生成了几个头文件:

wsdl2h -x -o dm.h http://www.onvif.org/onvif/ver10/device/wsdl/devicemgmt.wsdl -tC:\gsoap-2.8\gsoap\typemap.dat
wsdl2h -x -o an.h http://www.onvif.org/onvif/ver20/analytics/wsdl/analytics.wsdl -tC:\gsoap-2.8\gsoap\typemap.dat

之后,我编译了生成C ++服务代理和对象的标头:

soapcpp2.exe -j -S dm.h -IC:\gsoap-2.8\gsoap\import;C:\gsoap-2.8\gsoap -x -qDm
soapcpp2.exe -j -S an.h -IC:\gsoap-2.8\gsoap\import;C:\gsoap-2.8\gsoap -x -qAn

为了获得类似于gSOAP文档所述的应用程序: http : //www.cs.fsu.edu/~engelen/soapdoc2.html#tth_sEc7.2.8

在Visual Studio中进行编译时,出现以下错误:

error C3861: 'soap_in_PointerToSOAP_ENV__Fault': identifier not found
error C3861: 'soap_in_PointerToSOAP_ENV__Header': identifier not found
error C3861: 'soap_out_PointerToSOAP_ENV__Fault': identifier not found
error C3861: 'soap_out_PointerToSOAP_ENV__Header': identifier not found

我试图遵循文档中的说明( http://www.cs.fsu.edu/~engelen/soapdoc2.html#tth_sEc19.35 )关于由于定义WITH_NOGLOBAL根本不编译序列化程序,并编译了一个空环境.h文件,但这并不能解决问题。

我在网上搜索,但找不到任何解决方案。 该问题似乎与Header和Fault本身无关,而与指针有关。 对? 我该怎么办?

使用-q选项生成的代码似乎存在soap_in_PointerToSOAP_ENV__Faultsoap_in_PointerToSOAP_ENV__Header的命名空间问题。 仅1个wsdl也会发生相同的问题。

另一种方法是使用-p选项,如下所示:

soapcpp2.exe -j -S dm.h -IC:\gsoap-2.8\gsoap\import;C:\gsoap-2.8\gsoap -x -pDm
soapcpp2.exe -j -S an.h -IC:\gsoap-2.8\gsoap\import;C:\gsoap-2.8\gsoap -x -pAn

我遇到了这个问题,几乎想尽办法寻找解决方案。 我注意到使用#ifndef WITH_NOIDREF的指令封装了soap_(out|in)_PointerToSOAP_ENV__(Fault|Header) 然后,在使用WITH_NOIDREF定义的编译时,错误消息会有所减少。 因此,我手动封装了所有soap_(out|in)_PointerToSOAP_ENV__(Fault|Header)标识符,它起作用了!

例:

#ifndef WITH_NOIDREF
/// The soap_(out|in)_PointerToSOAP_ENV__(Fault|Header) indentifiers
// ...

#endif //WITH_NOIDREF

恐怕您正在使用Windows,但是我制作了一些脚本来自动化以下过程:

https://github.com/yudi-matsuzake/onvif-mkmakefile

这是解决方案。

  1. 运行wsdl2h -x -Nan -o an.h http://www.onvif.org/onvif/ver20/analytics/wsdl/analytics.wsdl 请注意,我在这里使用选项-Nan来让soapcpp2为该WSDL中的两个绑定定义的两个服务生成两个服务/代理类。 否则,您将获得一个服务/代理类,该类将两者结合在一起,形成一个类,这不是很优雅(但无论哪种方式都可以工作)。
  2. 运行wsdl2h -x -o dm.h http://www.onvif.org/onvif/ver20/analytics/wsdl/analytics.wsdl
  3. 创建一个新文件env.h
  4. 编辑env.h并添加#import "xop.h"#import "wsa5.h" 基本上,您希望将所有基于插件的标头都导入此处,因为插件必须与全局(非C ++命名空间)结构一起使用。 另外,可以通过添加struct SOAP_ENV__Header和/或struct SOAP_ENV__Detail结构来自定义env.h文件。 交换SOAP标头和特定的SOAP Fault详细信息是必需的。 在这种情况下,这是不需要的,因为#import "wsa5.h"已经为WS-Addressing定义了我们的SOAP标头。
  5. 运行soapcpp2 -penv env.h以生成全局SOAP Header和SOAP Fault序列化代码( envStub.henvH.henvC.cpp )。
  6. 编辑an.h并为SOAP Header和Faults添加以下定义

an.h:

struct SOAP_ENV__Header_
{
  // place SOAP Header elements here, if any
};
struct SOAP_ENV__Fault_
{
  char *faultcode;
  char *faultstring;
  char *faultactor;
  struct SOAP_ENV__Detail_ *detail;
  struct SOAP_ENV__Code_ *SOAP_ENV__Code;
  struct SOAP_ENV__Reason_ *SOAP_ENV__Reason;
  char *SOAP_ENV__Node;
  char *SOAP_ENV__Role;
  struct SOAP_ENV__Detail_ *SOAP_ENV__Detail;
};
struct SOAP_ENV__Detail_
{
  char *__any;
  int __type;
  void *fault;
};
struct SOAP_ENV__Code_
{
  char *SOAP_ENV__Value;
  struct SOAP_ENV__Code_ *SOAP_ENV__Subcode_;
};
struct SOAP_ENV__Reason_
{
  char *SOAP_ENV__Text;
};
  1. an.h更改行struct SOAP_ENV__Envelope { struct SOAP_ENV__Header_ *SOAP_ENV__Header; _XML SOAP_ENV__Body; }; struct SOAP_ENV__Envelope { struct SOAP_ENV__Header_ *SOAP_ENV__Header; _XML SOAP_ENV__Body; }; 通过使用struct SOAP_ENV__Header_而不是struct SOAP_ENV__Header
  2. an.h变线struct SOAP_ENV__Fault_* Fault使用struct SOAP_ENV__Fault_ ,而不是struct SOAP_ENV__Fault
  3. dm.h重复步骤6-8。
  4. 现在您可以使用C ++命名空间,因此运行soapcpp2 -j -x -qAn -I $GSOAPPATH/gsoap/import -I $GSOAPPATH/gsoap an.h可以在An命名空间中生成C ++服务和代理类(带有-qAn选项) 。
  5. 运行soapcpp2 -j -S -x -qDm -I $GSOAPPATH/gsoap/import -I $GSOAPPATH/gsoap dm.h
  6. 由于我们使用的是duration插件(此自定义序列化程序是可选的,请根据需要编辑typemap.dat以将其删除,然后重新运行wsdl2h),将$GSOAPPATH/custom/duration.c复制到本地duration.cpp .cpp(请注意.cpp扩展名) ,因为MSVC ++不喜欢将.c与.cpp源混合使用。
  7. 编辑duration.cpp并将#include "soapH.h"更改为#include "anH.h"
  8. 然后用您的代码编译整个程序,例如客户端c++ yourclientapp.cpp DmC.cpp AnC.cpp envC.cpp DmDeviceBindingProxy.cpp AnRuleEngineBindingProxy.cpp AnAnalyticsEngineBindingProxy.cpp stdsoap2.cpp dom.cpp duration.cpp或服务器端c++ yourserviceapp.cpp DmC.cpp AnC.cpp envC.cpp DmDeviceBindingService.cpp AnRuleEngineBindingService.cpp AnAnalyticsEngineBindingService.cpp stdsoap2.cpp dom.cpp duration.cpp
  9. 如果您使用的是WS-Addressing插件,请同时使用代码编译$GSOAPPATH/gsoap/plugin/wsaapi.c (但将wsaapi.c重命名为wsaapi.cpp因为MSVC ++不喜欢将.c与.cpp源代码混合使用)。

编辑

如果您按如下方式更改typemap.dat ,则可以跳过步骤6-8,然后使用修改后的typemap.dat重新运行typemap.dat

SOAP_ENV__Envelope  = struct SOAP_ENV__Envelope { struct SOAP_ENV__Header_ *SOAP_ENV__Header; _XML SOAP_ENV__Body; }; | struct SOAP_ENV__Envelope
SOAP_ENV__Header    = struct SOAP_ENV__Header_ { /* place SOAP Header elements here, if any */ }; | struct SOAP_ENV__Header_
SOAP_ENV__Fault     = \
struct SOAP_ENV__Fault_\
{\
  char *faultcode;\
  char *faultstring;\
  char *faultactor;\
  struct SOAP_ENV__Detail_ *detail;\
  struct SOAP_ENV__Code_ *SOAP_ENV__Code;\
  struct SOAP_ENV__Reason_ *SOAP_ENV__Reason;\
  char *SOAP_ENV__Node;\
  char *SOAP_ENV__Role;\
  struct SOAP_ENV__Detail_ *SOAP_ENV__Detail;\
};\
struct SOAP_ENV__Detail_\
{\
  char *__any;\
  int __type;\
  void *fault;\
};\
struct SOAP_ENV__Code_\
{\
  char *SOAP_ENV__Value;\
  struct SOAP_ENV__Code_ *SOAP_ENV__Subcode_;\
};\
struct SOAP_ENV__Reason_\
{\
  char *SOAP_ENV__Text;\
};\
| struct SOAP_ENV__Fault_

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM