[英]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__Fault
和soap_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,但是我制作了一些脚本来自动化以下过程:
这是解决方案。
wsdl2h -x -Nan -o an.h http://www.onvif.org/onvif/ver20/analytics/wsdl/analytics.wsdl
。 请注意,我在这里使用选项-Nan
来让soapcpp2为该WSDL中的两个绑定定义的两个服务生成两个服务/代理类。 否则,您将获得一个服务/代理类,该类将两者结合在一起,形成一个类,这不是很优雅(但无论哪种方式都可以工作)。 wsdl2h -x -o dm.h http://www.onvif.org/onvif/ver20/analytics/wsdl/analytics.wsdl
env.h
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标头。 soapcpp2 -penv env.h
以生成全局SOAP Header和SOAP Fault序列化代码( envStub.h
, envH.h
和envC.cpp
)。 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;
};
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
。 an.h
变线struct SOAP_ENV__Fault_* Fault
使用struct SOAP_ENV__Fault_
,而不是struct SOAP_ENV__Fault
。 dm.h
重复步骤6-8。 soapcpp2 -j -x -qAn -I $GSOAPPATH/gsoap/import -I $GSOAPPATH/gsoap an.h
可以在An
命名空间中生成C ++服务和代理类(带有-qAn
选项) 。 soapcpp2 -j -S -x -qDm -I $GSOAPPATH/gsoap/import -I $GSOAPPATH/gsoap dm.h
。 duration
插件(此自定义序列化程序是可选的,请根据需要编辑typemap.dat
以将其删除,然后重新运行wsdl2h),将$GSOAPPATH/custom/duration.c
复制到本地duration.cpp
.cpp(请注意.cpp扩展名) ,因为MSVC ++不喜欢将.c与.cpp源混合使用。 duration.cpp
并将#include "soapH.h"
更改为#include "anH.h"
。 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
。 $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.