使用gsoap时,soap信息自动添加一层不应该有的元素的问题

davelv 2010-04-02 09:30:19
最近在看CWMP协议,从Broadband官网下载了CWMP协议格式的schema文件,链接如下:http://www.broadband-forum.org/cwmp/cwmp-1-1.xsd

然后用gsoap2.7.15版本(http://sourceforge.net/projects/gsoap2/files/)中的 wsdl2h转化xsd为头文件,并在头文件里面手工添加方法(xsd文件不包含方法,wsdl文件才会包含,但是官方未提供),再用soapcpp2 转化为 soap通信的源代码文件,由于只会C语言所以都是C格式,非Cpp。

上面过程简单描述如下:cwmp通信格式的schema文件(通过wsdl2h)-->原始头文件(通过手工添加方法)-->修改后的头文件(通过soapcpp2)-->符合cwmp协议的源代码

然后写demo,调试,发现了一个问题。例如我的schema文件中有一个信息的结构如下:

<!-- Inform -->

<xs:element name="Inform">

<xs:annotation>

<xs:documentation>Inform message - Annex A.3.3.1</xs:documentation>

</xs:annotation>

<xs:complexType>

<xs:sequence>

<xs:element name="DeviceId" type="tns:DeviceIdStruct"/>

<xs:element name="Event" type="tns:EventList"/>

<xs:element name="MaxEnvelopes" type="xs:unsignedInt"/>

<xs:element name="CurrentTime" type="xs:dateTime"/>

<xs:element name="RetryCount" type="xs:unsignedInt"/>

<xs:element name="ParameterList" type="tns:ParameterValueList"/>

</xs:sequence>

</xs:complexType>

</xs:element>


通过转换生成的结构体如下:

/* CWMP:Inform */
struct _CWMP__Inform
{
struct CWMP__DeviceIdStruct *DeviceId; /* required element of type CWMP:DeviceIdStruct */
struct EventList *Event; /* required element of type ArrayOfEventStruct */
unsigned int MaxEnvelopes; /* required element of type xsd:unsignedInt */
time_t CurrentTime; /* required element of type xsd:dateTime */
unsigned int RetryCount; /* required element of type xsd:unsignedInt */
struct ParameterValueList *ParameterList; /* required element of type ArrayOfParameterValueStruct */
};

我在修改后的头文件里手工写入的方法如下:

int CWMP__Inform(struct _CWMP__Inform *Inform_Message, struct _CWMP__InformResponse *InformRes_Message);

最终源码中转出来的三个方法使用了上述结构体,存根如下:

//主体方法
int CWMP__Inform(struct soap*, struct _CWMP__Inform *CWMP__InformMessage, struct _CWMP__InformResponse *CWMP__InformResponseMessage);
//客户端方法
int soap_call_CWMP__Inform(struct soap *soap, const char *soap_endpoint, const char *soap_action, struct _CWMP__Inform *CWMP__InformMessage, struct _CWMP__InformResponse *CWMP__InformResponseMessage);
//服务端方法
SOAP_FMAC5 int SOAP_FMAC6 soap_serve_CWMP__Inform(struct soap*);

以上都没有任何问题,问题就出来gsoap就自作主张的为方法包装了一个结构体:

/* CWMP:Inform */
struct CWMP__Inform
{
struct _CWMP__Inform *CWMP__InformMessage; /* optional element of type CWMP:Inform */
};

然后使用了这个结构体把soap进一步包装,于是soap信息中就多了一层元素。

正规的Inform消息格式如下:

<cwmp:Inform>
<DeviceId xsi:type="cwmp:DeviceIdStruct">
<Manufacturer xsi:type="xsd:string">kingsoft </Manufacturer>
<OUI xsi:type="xsd:string">FFFFFF </OUI>
<ProductClass xsi:type="xsd:string">UTM </ProductClass>
<SerialNumber xsi:type="xsd:string">FFFFFFFFF</SerialNumber>
</DeviceId>
<Event xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="cwmp:EventStruct[0]"></Event>
<MaxEnvelopes xsi:type="xsd:unsignedInt">1</MaxEnvelopes>
<CurrentTime xsi:type="xsd:dateTime">2010-04-01T05:15:35</CurrentTime>
<RetryCount xsi:type="xsd:unsignedInt">0</RetryCount>
<ParameterList xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="cwmp:ParameterValueStruct[0]"></ParameterList>
</cwmp:Inform>

但是实际上产生的soap消息结果如下:

<cwmp:Inform>
<cwmp:InformMessage>
<DeviceId xsi:type="cwmp:DeviceIdStruct">
<Manufacturer xsi:type="xsd:string">kingsoft </Manufacturer>
<OUI xsi:type="xsd:string">FFFFFF </OUI>
<ProductClass xsi:type="xsd:string">UTM </ProductClass>
<SerialNumber xsi:type="xsd:string">FFFFFFFFF</SerialNumber>
</DeviceId>
<Event xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="cwmp:EventStruct[0]"></Event>
<MaxEnvelopes xsi:type="xsd:unsignedInt">1</MaxEnvelopes>
<CurrentTime xsi:type="xsd:dateTime">2010-04-01T05:15:35</CurrentTime>
<RetryCount xsi:type="xsd:unsignedInt">0</RetryCount>
<ParameterList xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="cwmp:ParameterValueStruct[0]"></ParameterList>
</cwmp:InformMessage>
</cwmp:Inform>

于是就很杯具了,而且别的方法也是如此,xsd明明定义的很规范了,它还自己往上加东西,有没有哪位同志对gsoap比较了解,能帮忙解决这个问题吗?

如果有不清楚的可以留言,谢谢大家。
...全文
403 4 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
学习万物互联 2012-04-13
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
手工修改解决的。把.h文件的函数参数分拆就可以了。
[/Quote]

这个函数分拆怎么做啊?

int CWMP1__Inform(struct _CWMP1__Inform* informReq, struct _CWMP1__InformResponse* informRes);
Garibaldi 2011-10-25
  • 打赏
  • 举报
回复
应该是wsdl文件格式的问题, 请确认wsdl文件正确.

下面有现成的wsdl文件
http://my-svn.assembla.com/svn/cwmp/src/parser/wsdl/
davelv 2010-06-18
  • 打赏
  • 举报
回复
手工修改解决的。把.h文件的函数参数分拆就可以了。
tonyroy 2010-06-08
  • 打赏
  • 举报
回复
我刚好也在进行CWMP协议开发,请问楼主这个问题解决了吗?

24,860

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧