这是空指针问题的解引用-在ANSI C&gSoap域中:
我正在使用以下公共WSDL:
http://www.mobilefish.com/services/web_service/countries.php?wsdl
并使用soapUI测试了它的行为。
我使用wsdl2h和soapcpp2实用程序创建了仅限客户端的ANSI C绑定。
我的问题:
在以前的gsoap项目中,客户机soap_调用函数(第五个参数)中的results结构不需要初始化,只需要如下内容:
struct ns2__countryInfoByIanaResponse out, *pOut
pOut= &out;
在这个项目之前,这一直是足够的。
客户端soap_调用如下所示:
soap_call_ns2__countryInfoByIana(&soap, NULL, NULL, pIn, pOut); /* SOAP 1.2 RPC return element...*/
此项目的pIn被定义为char*,填充有两个字符的IANA代码,如“us”或“nz”这个特定调用的返回结构pOut的形状如下:
struct ns2__countryInfoByIanaResponse
{
struct ns1__CountryData *countryinfo;
}
ns1_uuuCountryData的形状如下:
struct ns1__CountryData
{
char *ianacode; /* required element of type xsd:string */
char *countryname; /* required element of type xsd:string */
float latitude; /* required element of type xsd:float */
float longitude; /* required element of type xsd:float */
};
因此,我的应用程序对此函数的调用设置如下:
//declare response structure:
struct ns2__countryInfoByIanaResponse o, *pO;
void main(void)
{
pO = &o;
if(GetCountryInfo(buf, pO)==0)
{
pO->countryinfo->countryname; **Error Occurs Here...**
}
}
错误发生在pO->countryinfo,作为空指针的解引用
GetCountryInfo在此定义:
int DLL_EXPORT GetCountryInfo(char *pIn, struct ns2__countryInfoByIanaResponse *pOut)
{
int status = 0;
size_t len=2048;
char buf[2048];
if (soap_call_ns2__countryInfoByIana(&soap, NULL, NULL, pIn, pOut)== SOAP_OK)
{
status = 0;
}
else
{
//soap_print_fault(&soap, stderr);
soap_sprint_fault(&soap, buf, len);
MessagePopup("soap error", buf);
status = 1;
}
return status;
}
因此,这似乎是一个组合的ANSI C/gSoap问题:过去的其他项目,具有非常相似的输出结构形状(即包含char*结构的结构)在初始化时返回完全填充的结果,除了上面所示的内容。
有什么想法吗请让我知道,如果我能提供任何进一步的细节。
谢谢。
最佳答案
在我看来,soap服务器有一个bugcountryInfoByIana函数的soap响应示例如下:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<SOAP-ENV:countryInfoByIanaResponse>
<return>
<ianacode xsi:type="xsd:string">nz</ianacode>
<countryname xsi:type="xsd:string">New Zealand</countryname>
<latitude xsi:type="xsd:float">-40.900558</latitude>
<longitude xsi:type="xsd:float">174.885971</longitude>
</return>
</SOAP-ENV:countryInfoByIanaResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
<SOAP-ENV:countryInfoByIanaResponse>
应该有不同的命名空间。这是WSDL的一部分,它包含相同(无效)的命名空间。
<operation name="countryInfoByIana">
<soap:operation soapAction="http://schemas.xmlsoap.org/soap/envelope/#Countries#countryInfoByIana" />
<input>
<soap:body use="encoded" namespace="http://schemas.xmlsoap.org/soap/envelope/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</input>
<output>
<soap:body use="encoded" namespace="http://schemas.xmlsoap.org/soap/envelope/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</output>
</operation>
编辑:
关于soapUI为什么工作良好的问题;soapUI可能不像gsoap那样验证返回值。
我使用gsoap 2.7成功地在我的电脑上运行了这个程序:
在soapClient.c第56行中,更改以下行:
//soap_get_ns2__countryInfoByIanaResponse(soap, _param_1, "ns2:countryInfoByIanaResponse", "");
soap_get_ns2__countryInfoByIanaResponse(soap, _param_1, "SOAP-ENV:countryInfoByIanaResponse", "");
在soapC.c第1470行中,更改以下行:
//if (soap_in_PointerTons1__CountryData(soap, "countryinfo", &a->countryinfo, "ns1:CountryData"))
if (soap_in_PointerTons1__CountryData(soap, "return", &a->countryinfo, "ns1:CountryData"))//return
但我认为你不应该这样解决问题不仅因为这两个文件都是生成的,所以当再次生成时,您将丢失更改。
关于c - gSoap-服务调用以SOAP OK返回,但未初始化结构,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5757762/