C语言 gSoap -服务调用返回SOAP_OK,但返回未初始化的结构

yk9xbfzb  于 2023-03-28  发布在  其他
关注(0)|答案(1)|浏览(123)

这是一个 * 取消引用空指针 * 的问题-在ANSI C和gSoap域中:
我正在使用以下公共WSDL

http://www.mobilefish.com/services/web_service/countries.php?wsdl

并使用soapUI测试了它的行为。
我使用wsdl 2 h和soapcpp 2实用程序创建了仅限客户端的ANSIC绑定。

  • 问题:*

在以前的gsoap项目中,客户端soap_call函数(第五个参数)中的结果结构不需要初始化,只需要如下内容:

struct ns2__countryInfoByIanaResponse out, *pOut
pOut= &out;

在这个项目之前,这一直是足够的。
客户端soap_call如下所示:

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__CountryData的形状如下:

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;
}

其他使用类似输出结构形状的gSoap项目(即包含char * 结构的结构)在初始化时返回完全填充的结果,除了我上面显示的之外。
有什么想法吗?如果我能提供任何进一步的细节,请让我知道。谢谢。

jqjz2hbq

jqjz2hbq1#

在我看来,soap服务器有一个bug。countryInfoByIana函数的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那样验证返回值。
我使用gsoap2.7成功地让程序在我的pc上运行:
在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

但我认为你不应该这样解决问题。不仅因为两个文件都是生成的,所以当你再次生成它时,你会丢失你的更改。

相关问题