然后用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比较了解,能帮忙解决这个问题吗?
如果有不清楚的可以留言,谢谢大家。