Click here to Skip to main content
11,707,470 members (73,352 online)
Click here to Skip to main content

CurrencyConvertor - How use gSOAP and WebServices - Part 2 Doing the first WS client.

, 9 Mar 2007 CPOL 139.5K 1.7K 36
Rate this:
Please Sign up or sign in to vote.
Part 2: How to use the classes generated with gSOAP.

Introduction

This is the second of two articles where I explain building a web service client from wsdl file. With Part One, I explained how to get the class from the wsdl file to be used in VC++ 6. In Part Two, I will show you how to use the classes generated with gSOAP in Part One.

Using the code

Usually in the file soap*****************SoapProxy.h we can find the class definition of generic WS. In this case, soapCurrencyConvertorSoapProxy.h, I have already included it in Part One.

//soapCurrencyConvertorSoapProxy.h

#ifndef soapCurrencyConvertorSoap_H
#define soapCurrencyConvertorSoap_H
#include "soapH.h"
class CurrencyConvertorSoap
{   public:
    struct soap *soap;
    const char *endpoint;
    CurrencyConvertorSoap()
    { soap = soap_new(); endpoint = 
        "http://www.webservicex.net/CurrencyConvertor.asmx";
        if (soap && !soap->namespaces) 
        { static const struct Namespace namespaces[] = 
{
    {"SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/", 
        "http://www.w3.org/*/soap-envelope", NULL},
    {"SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/", 
        "http://www.w3.org/*/soap-encoding", NULL},
    {"xsi", "http://www.w3.org/2001/XMLSchema-instance", 
        "http://www.w3.org/*/XMLSchema-instance", NULL},
    {"xsd", "http://www.w3.org/2001/XMLSchema", 
         "http://www.w3.org/*/XMLSchema", NULL},
    {"ns1", "http://www.webserviceX.NET/", NULL, NULL},
    {NULL, NULL, NULL, NULL}
};
    soap->namespaces = namespaces; } };
    virtual ~CurrencyConvertorSoap() { if (soap) { soap_destroy(soap); 
        soap_end(soap); soap_done(soap); soap_del(soap); } };
    virtual int __ns1__ConversionRate(_ns1__ConversionRate 
        *ns1__ConversionRate, _ns1__ConversionRateResponse     
        *ns1__ConversionRateResponse) 
        { return soap ? soap_call___ns1__ConversionRate(soap, 
            endpoint, NULL, ns1__ConversionRate, 
            ns1__ConversionRateResponse) : SOAP_EOM; };
};
#endif

In this case, the method is only one and it is __ns1__ConversionRate .

The class takes two params. The first is the input (the two currencies) and the second is the output (the result).

Before you use the class method of WS you must instantiate the param with soap_instantiate(), and with soap, from your CurrencyConvertor example.

pConversionRate = (_ns1__ConversionRate*) 
    soap_instantiate(m_pCurrencyConvertor->soap,
    SOAP_TYPE__ns1__ConversionRate,"",
    "",pConversionRateSize);
    
    and 

pConversionRateResponse = (_ns1__ConversionRateResponse*) 
    soap_instantiate(m_pCurrencyConvertor->soap, 
    SOAP_TYPE__ns1__ConversionRateResponse,\
        "","",pConversionRateResponseSize);

This returns an int that is SOAP_OK, if all is well. (Note: You can find all other definitions for errors in stdsopa2.h)

If this did not return SOAP_OK you can use soap_print_fault to get the error string.

In the file Soaph.h you can find methods you can use, like soap_s2ns1__Currency or soap_ns1__Currency2s. Just as the name explains, they are used to convert the currency to string and vice versa.

Using the code CMyCurrencyConvertor

For the test I have develop a new class CMyCurrencyConvertor that replaces the methods of CurrencyConvertor.

The class CMyCurrencyConvertor instantiates all the created pointers itself.

I have made only a few public methods and I use them in the dialog.

Constructor

In the constructor I dynamically allocate at run time the object CurrencyConvertorSoap.

CMyCurrencyConvertor::CMyCurrencyConvertor()
{
    m_pCurrencyConvertor= new CurrencyConvertorSoap;    
}

Destructor

In the destructor I delete the memory allocated for CurrencyConvertorSoap.

CMyCurrencyConvertor::~CMyCurrencyConvertor()
{    
    delete m_pCurrencyConvertor;    
}

Instantiate

I have two instantiates for the params, InstantiateRate and InstantiateRateResponse.

_ns1__ConversionRate * CMyCurrencyConvertor::InstantiateRate()
{    
    _ns1__ConversionRate *pConversionRate;
    size_t *pConversionRateSize = new size_t;
    *pConversionRateSize = sizeof(_ns1__ConversionRate);

    pConversionRate = (_ns1__ConversionRate*)
        soap_instantiate(m_pCurrencyConvertor->soap,
        SOAP_TYPE__ns1__ConversionRate,"","",
        pConversionRateSize);
    
    delete pConversionRateSize ;

    return pConversionRate;
}

_ns1__ConversionRateResponse * CMyCurrencyConvertor::InstantiateRateResponse()
{    
    _ns1__ConversionRateResponse *pConversionRateResponse;
    size_t *pConversionRateResponseSize = new size_t;
    *pConversionRateResponseSize = sizeof(_ns1__ConversionRateResponse);

    pConversionRateResponse = (_ns1__ConversionRateResponse*) 
        soap_instantiate(m_pCurrencyConvertor->soap , \
        SOAP_TYPE__ns1__ConversionRateResponse,"",
        "",pConversionRateResponseSize);
    
    delete pConversionRateResponseSize ;

    return pConversionRateResponse;
}

GetConversionRate

I take two methods, one takes the input of string Code for currency and the other takes the type of code for currency.

bool CMyCurrencyConvertor::GetConversionRate(ns1__Currency oFromCurrencyCode,
    ns1__Currency oToCurrencyCode, double &dRate)
{
    int iRet = SOAP_ERR;
    
    _ns1__ConversionRate            *pConversionRate;
    _ns1__ConversionRateResponse    *pConversionRateResponse;
    
    pConversionRate = InstantiateRate();
    pConversionRateResponse = InstantiateRateResponse();

    pConversionRate->FromCurrency = oFromCurrencyCode;
    pConversionRate->ToCurrency = oToCurrencyCode;

    iRet = m_pCurrencyConvertor->__ns1__ConversionRate(pConversionRate,
         pConversionRateResponse);
    
    switch(iRet)
    {
    case SOAP_OK :
        {
            dRate = pConversionRateResponse->ConversionRateResult;
            return true;
        }
            /*
        case SOAP_CLI_FAULT            
        case SOAP_SVR_FAULT            
        case SOAP_TAG_MISMATCH        
        case SOAP_TYPE            
        case SOAP_SYNTAX_ERROR        
        case SOAP_NO_TAG            
        case SOAP_IOB            
        case SOAP_MUSTUNDERSTAND        
        ...
        */
    default:
        {
            Log(GetSoapError());              
        }
    }    
    return false;
}

I create the two param pointers and instantiate it. I set the two currency code and call the ConversionRate.

If all works fine, I return the conversion, otherwise I return an error.

// Conversion from String code
bool CMyCurrencyConvertor::GetConversionRate(CString sFromCurrencyCode,
    CString sToCurrencyCode, double &dRate)
{
    ns1__Currency oFromCurrencyCode; 
    ns1__Currency oToCurrencyCode;

    int iRetFromCurrencyCode = soap_s2ns1__Currency
      (m_pCurrencyConvertor->soap,sFromCurrencyCode, 
      &oFromCurrencyCode);

    int iRetToCurrencyCode = soap_s2ns1__Currency
      (m_pCurrencyConvertor->soap,sToCurrencyCode, 
      &oToCurrencyCode);

    return GetConversionRate(oFromCurrencyCode,oToCurrencyCode,dRate);    
}

With this method you can call the function without knowing the internal type. For the conversion I use the function soap_s2ns1__Currency.

GetSoapError

I add another method for retrieving the error from soap to string.

CString CMyCurrencyConvertor::GetSoapError()
{ 
    struct soap *pSoap = m_pCurrencyConvertor->soap;
    CString sError;
    if (soap_check_state(pSoap ))
        sError.Format("Error: soap struct not initialized\n");
    else
    {
        if (pSoap->error)
        { 
            const char *pFaultCode, *pFaultSubCode = NULL, *pFalutString, 
                **iFaultCode;
            iFaultCode = soap_faultcode(pSoap );
            if (!*iFaultCode)
                soap_set_fault(pSoap );
            pFaultCode = *iFaultCode;
            if (pSoap ->version == 2)
                pFaultSubCode = *soap_faultsubcode(pSoap );
            pFalutString = *soap_faultstring(pSoap );
            iFaultCode = soap_faultdetail(pSoap );
            sError.Format("%s%d fault: %s [%s]\"%s\"Detail: %s", 
                pSoap->version ? "SOAP 1." :\
            "Error ", pSoap->version ? (int)pSoap->version : pSoap->error, 
                pFaultCode, \
            pFaultSubCode ? pFaultSubCode : "no subcode", 
                pFalutString ? pFalutString : "[no reason]", \
            iFaultCode && *iFaultCode ? *iFaultCode : "[no detail]");
        }
    }
    return sError;
}

String2Currency, Currency2String

This is a useful function to convert currency to printable string and vice versa:

bool CMyCurrencyConvertor::String2Currency(CString sCurrencyCode,
     ns1__Currency &oCurrencyCode)
{
    int iRet = soap_s2ns1__Currency(m_pCurrencyConvertor->soap,
        sCurrencyCode, &oCurrencyCode);

    switch(iRet)
    {
    case SOAP_OK :
        {            
            return true;
        }
            /*
        case SOAP_CLI_FAULT            
        case SOAP_SVR_FAULT            
        case SOAP_TAG_MISMATCH        
        case SOAP_TYPE            
        case SOAP_SYNTAX_ERROR        
        case SOAP_NO_TAG            
        case SOAP_IOB            
        case SOAP_MUSTUNDERSTAND        
        ...
        */
    default:
        {
            Log(GetSoapError());              
        }
    }    
    return false;
}

bool CMyCurrencyConvertor::Currency2String(ns1__Currency oCurrencyCode,
     CString &sCurrencyCode)
{
    const char* sName = 
        soap_ns1__Currency2s(m_pCurrencyConvertor->soap,oCurrencyCode);
    if (sName != NULL)
    {
        CString sTMP(sName);
        sCurrencyCode = sTMP;
        return true;
    }
    else
        Log(GetSoapError());                          
    return false;
}

Using the code in dialog

I created a dialog project and I use the methods I describe again.

I take a cycle for retrieval, and display the currency code, like this:

CString sCodeName;
    for (int iDx=ns1__Currency__AFA; iDx <;ns1__Currency__TRY+1; iDx++)
    {
        m_oMyCurrencyConvertor.Currency2String((ns1__Currency) iDx,
            sCodeName);

        m_cboFromCurrency.AddString(sCodeName);    
        m_cboToCurrency.AddString(sCodeName);    
    }    

When you push a button I retrieve the currency codes selected and use GetConversionRate to call WS.

double dRate;
CString sFromCurrency,sToCurrency;

m_cboFromCurrency.GetWindowText(sFromCurrency);
m_cboToCurrency.GetWindowText(sToCurrency);

if (m_oMyCurrencyConvertor.GetConversionRate(sFromCurrency,
    sToCurrency,dRate))
{
    int iColumnCount = m_lstConversionRate.GetItemCount();
    CString sRate;
    sRate.Format("%f",dRate);
    m_lstConversionRate.InsertItem(iColumnCount,sFromCurrency);
    m_lstConversionRate.SetItemText(iColumnCount,iIDX_TO,sToCurrency);
    m_lstConversionRate.SetItemText(iColumnCount,iIDX_CONVERSION,sRate);
}

Use it however you wish.

History

  • 12/07/2006: First release

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Dr.Luiji
Software Developer (Senior) Welcome Italia spa
Italy Italy
Bertoneri Luigi, alias Dr.Luiji
Bachelor of Science in Computer Science, year 2K - University of Pisa (Italy).

I'm a developer with more than 10 years of experience. I like the new technology, Windows, iOS and Android.
I love challenges.

Skills:
- Language: Android, Objective-C, C++, C#, Java
- Platform: Windows, .NET
- Technology: Too much...

I currently work and live in Italy.
Music I listen to: Tool, Slipknot, NIN, Korn, Perfect Circle, Dry Kill Logic, Godsmack, and more.

You may also be interested in...

Comments and Discussions

 
QuestionHow to pass header information to the soap header SOAP_ENV__Header, in c++ using gsoap Pin
Member 147055627-Sep-11 3:37
memberMember 147055627-Sep-11 3:37 
AnswerRe: How to pass header information to the soap header SOAP_ENV__Header, in c++ using gsoap Pin
Dr.Luiji27-Sep-11 11:10
memberDr.Luiji27-Sep-11 11:10 
GeneralRe: How to pass header information to the soap header SOAP_ENV__Header, in c++ using gsoap Pin
Member 147055627-Sep-11 19:40
memberMember 147055627-Sep-11 19:40 
GeneralRe: How to pass header information to the soap header SOAP_ENV__Header, in c++ using gsoap Pin
Member 147055628-Sep-11 4:33
memberMember 147055628-Sep-11 4:33 
Questioncalling web service with complex parameters Pin
AmVal12-Jul-11 3:10
memberAmVal12-Jul-11 3:10 
AnswerRe: calling web service with complex parameters Pin
Dr.Luiji14-Jul-11 9:51
memberDr.Luiji14-Jul-11 9:51 
GeneralRe: calling web service with complex parameters Pin
AmVal14-Jul-11 10:10
memberAmVal14-Jul-11 10:10 
GeneralRe: calling web service with complex parameters Pin
Dr.Luiji14-Jul-11 10:32
memberDr.Luiji14-Jul-11 10:32 
GeneralRe: calling web service with complex parameters Pin
AmVal14-Jul-11 10:45
memberAmVal14-Jul-11 10:45 
GeneralRe: calling web service with complex parameters [modified] Pin
Dr.Luiji14-Jul-11 11:23
memberDr.Luiji14-Jul-11 11:23 
GeneralRe: calling web service with complex parameters Pin
AmVal15-Jul-11 9:13
memberAmVal15-Jul-11 9:13 
GeneralRe: calling web service with complex parameters Pin
AmVal15-Jul-11 9:43
memberAmVal15-Jul-11 9:43 
GeneralRe: calling web service with complex parameters Pin
Dr.Luiji15-Jul-11 20:40
memberDr.Luiji15-Jul-11 20:40 
GeneralMy vote of 5 Pin
Absa28-Feb-11 23:34
memberAbsa28-Feb-11 23:34 
GeneralRe: My vote of 5 Pin
Dr.Luiji14-Jul-11 9:53
memberDr.Luiji14-Jul-11 9:53 
Questionmemory leak? Pin
laoheshang6-Aug-10 4:13
memberlaoheshang6-Aug-10 4:13 
AnswerRe: memory leak? Pin
Dr.Luiji8-Sep-10 22:45
memberDr.Luiji8-Sep-10 22:45 
GeneralDoubt regarding minOccurs [modified] Pin
naveen_naik2-Feb-09 21:41
membernaveen_naik2-Feb-09 21:41 
GeneralRe: Doubt regarding minOccurs Pin
Dr.Luiji5-Feb-09 2:17
memberDr.Luiji5-Feb-09 2:17 
GeneralSilly doubt.. What is 'g' in gSOAP Pin
naveen_naik29-Jan-09 0:05
membernaveen_naik29-Jan-09 0:05 
JokeRe: Silly doubt.. What is 'g' in gSOAP Pin
Dr.Luiji29-Jan-09 1:59
memberDr.Luiji29-Jan-09 1:59 
GeneralRe: Silly doubt.. What is 'g' in gSOAP Pin
hashimsaleem17-Feb-10 22:58
memberhashimsaleem17-Feb-10 22:58 
Questionwsdl2h complier Pin
naveen_naik28-Jan-09 19:30
membernaveen_naik28-Jan-09 19:30 
GeneralRe: wsdl2h complier [modified] Pin
Dr.Luiji29-Jan-09 2:13
memberDr.Luiji29-Jan-09 2:13 
GeneralRe: wsdl2h complier Pin
naveen_naik29-Jan-09 19:16
membernaveen_naik29-Jan-09 19:16 
GeneralRe: wsdl2h complier Pin
Dr.Luiji30-Jan-09 4:59
memberDr.Luiji30-Jan-09 4:59 
Generalusing the webservice in a multithread application Pin
monsieur_jj1-Sep-08 16:25
membermonsieur_jj1-Sep-08 16:25 
GeneralRe: using the webservice in a multithread application Pin
Dr.Luiji3-Sep-08 10:09
memberDr.Luiji3-Sep-08 10:09 
GeneralRe: using the webservice in a multithread application Pin
monsieur_jj12-Oct-08 17:23
membermonsieur_jj12-Oct-08 17:23 
GeneralRe: using the webservice in a multithread application Pin
Dr.Luiji13-Oct-08 0:40
memberDr.Luiji13-Oct-08 0:40 
QuestionHow to deploy a gsoap server on unix Pin
naveen_naik21-Jul-08 2:34
membernaveen_naik21-Jul-08 2:34 
AnswerRe: How to deploy a gsoap server on unix Pin
Dr.Luiji21-Jul-08 7:17
memberDr.Luiji21-Jul-08 7:17 
GeneralRe: How to deploy a gsoap server on unix [modified] Pin
naveen_naik21-Jul-08 19:50
membernaveen_naik21-Jul-08 19:50 
GeneralRe: How to deploy a gsoap server on unix Pin
Dr.Luiji22-Jul-08 9:52
memberDr.Luiji22-Jul-08 9:52 
QuestionHow to use Unicode in gSoap? Pin
banthan19829-Jul-08 21:35
memberbanthan19829-Jul-08 21:35 
AnswerRe: How to use Unicode in gSoap? Pin
Dr.Luiji10-Jul-08 20:55
memberDr.Luiji10-Jul-08 20:55 
AnswerRe: How to use Unicode in gSoap? Pin
DirectX7723-Apr-09 6:43
memberDirectX7723-Apr-09 6:43 
Questionif http server don't support cgi,how I add gsoap to http server? Pin
Member #30192502-Jul-08 0:17
memberMember #30192502-Jul-08 0:17 
AnswerRe: if http server don't support cgi,how I add gsoap to http server? [modified] Pin
Dr.Luiji2-Jul-08 1:18
memberDr.Luiji2-Jul-08 1:18 
GeneralRe: if http server don't support cgi,how I add gsoap to http server? Pin
Dr.Luiji2-Jul-08 2:16
memberDr.Luiji2-Jul-08 2:16 
GeneralRe: if http server don't support cgi,how I add gsoap to http server? Pin
Member #30192502-Jul-08 16:18
memberMember #30192502-Jul-08 16:18 
GeneralRe: if http server don't support cgi,how I add gsoap to http server? Pin
Member #30192502-Jul-08 17:28
memberMember #30192502-Jul-08 17:28 
GeneralRe: if http server don't support cgi,how I add gsoap to http server? Pin
Dr.Luiji2-Jul-08 20:49
memberDr.Luiji2-Jul-08 20:49 
GeneralRe: if http server don't support cgi,how I add gsoap to http server? Pin
Member #30192503-Jul-08 17:27
memberMember #30192503-Jul-08 17:27 
AnswerRe: if http server don't support cgi,how I add gsoap to http server? Pin
浪迹天涯7-Sep-08 22:30
member浪迹天涯7-Sep-08 22:30 
GeneralRe: if http server don't support cgi,how I add gsoap to http server? Pin
Dr.Luiji10-Sep-08 10:10
memberDr.Luiji10-Sep-08 10:10 
GeneralCreate a Web server Pin
almc16-Apr-08 7:17
memberalmc16-Apr-08 7:17 
GeneralRe: Create a Web server Pin
Dr.Luiji 17-Apr-08 10:13
member Dr.Luiji 17-Apr-08 10:13 
GeneralRe: Create a Web server Pin
Dr.Luiji15-Jul-08 10:44
memberDr.Luiji15-Jul-08 10:44 
QuestionCan I generate custom header? Pin
vladpol198226-Feb-08 23:34
membervladpol198226-Feb-08 23:34 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150819.1 | Last Updated 9 Mar 2007
Article Copyright 2007 by Dr.Luiji
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid