gSoap - вызов службы возвращается с SOAP_OK, но возвращает структуру, унифицированную - PullRequest
2 голосов
/ 22 апреля 2011

Это разыменование нулевого указателя проблема - в обоих ANSI C & gSoap доменах:

Я использую следующий публичный WSDL:

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

и проверили его поведение с помощью soapUI.
Я создал только привязки ANSI C на стороне клиента с помощью утилит wsdl2h и soapcpp2.

Моя проблема:

В предыдущих проектах 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 для этого проекта определяется как символ *, заполненный двухсимвольным кодом 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;
}

Итак, это, кажется, комбинация ANSI C / gSoap вопрос: другие проекты в прошлом, с очень похожими формами выходной структуры (т.е. структуры, содержащие структуры, содержащие char *) возвращает полностью заполненные результаты, когда инициализируется только с тем, что я показал выше.

Есть идеи? Пожалуйста, дайте мне знать, если я могу предоставить более подробную информацию. Спасибо.

1 Ответ

1 голос
/ 23 апреля 2011

Мне кажется, что у мыльного сервера есть ошибка.Пример мыльного ответа от функции countryInfoByIana выглядит следующим образом:

<?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:

В строке 56 soapClient.c измените эту строку:

//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

Но я не думаю, что вы должны решать проблемы таким образом.Не только потому, что оба файла сгенерированы, поэтому вы потеряете свои изменения при повторном создании.

...