二.gsoap簡單使用(解決中文亂碼、代碼冗餘、可控釋放)

上篇:c++訪問webservice(gsoap簡單使用)

         上篇文章使用gsoap命令行生成代理的方式進行webservice的訪問。但在使用中存在一些問題,比如中文亂碼、調用接口方式存在代碼冗餘(實現每個接口都要進行參數初始化、代理初始化及接口調用、結果判斷及返回)、實例對象會被代理類釋放等問題。

         爲了解決這些問題,可以採用宏的方式。下面是我實現的一個管理類,首先展示下效果:

 

原始:

ns1__Person* PersonUser::GetPerson(char* pid,double salary)

{

    Service1SoapProxy proxy("",SOAP_C_UTFSTRING);

    _ns1__GetPerson gp;

    gp.pid = pid;

    gp.salary = salary;

    _ns1__GetPersonResponse gpr;

    ns1__Person* pPerson = NULL;

    if (proxy.GetPerson(&gp,gpr) == SOAP_OK)

    {

        pPerson = gpr.GetPersonResult;

    }

    return pPerson;

}

 

使用宏以後:

ns1__Person* PersonUser::GetPerson(char* pid,double salary)

{

    ns1__Person* pPerson = NULL;

    REGISTERMETHOD(GetPerson)

    REGISTERVAR(pid)

    REGISTERVAR(salary)

    REGISTERENDNS(GetPerson,pPerson)

    return pPerson;

}

 

明顯代碼結構變得更加清晰,並且可以在其中附加一些其他功能。下面就對這個類簡單講解下:

#define REGISTERMETHOD(methodName)\

    _ns1__##methodName mn;\

    _ns1__##methodName##Response mnr;\

 

這裏使用一行宏定義了_ns1__GetPerson_ns1__GetPersonResponse。可以根據傳遞的接口名定義該接口對應的接口類和影響類。

 

#define REGISTERVAR(variable)\

    mn.##variable=variable;\

這個宏函數用來對接口參數進行賦值操作。

 

#define REGISTERENDNS(methodName,result)\

    if (!m_pSoapProxy)\

    m_pSoapProxy = new Service1SoapProxy(m_SoapUrl,SOAP_C_MBSTRING);\

    if(m_pSoapProxy->##methodName##(&mn,mnr)==SOAP_OK){\

    result = mnr.##methodName##Result;\

    result->soap->user=m_pSoapProxy;\

    }\

這個宏函數主要解決代碼冗餘問題,用來接收返回的結果並把代理對象記錄到返回實體類中,後續便於實體類及代理對象的內存釋放。由於代理類使用指針方式,因此可以保證我們需要釋放時纔會對其進行釋放。

 

#include "JCSoapManager.h"

#include "Service1Soap.nsmap"

char JCSoapManager::m_SoapUrl[256]={0};

 

JCSoapManager::JCSoapManager(void)

    :m_pSoapProxy(NULL)

{

}

 

 

JCSoapManager::~JCSoapManager(void)

{

}

 

void JCSoapManager::InitSoapUrl(const string soapUrl)

{

    setlocale(LC_ALL, "");

    ZeroMemory(m_SoapUrl,256);

    int len = soapUrl.length();

    memcpy_s(m_SoapUrl,256,soapUrl.c_str(),len);

}

 

void JCSoapManager::Destory(soap* soap)

{

    if (soap&&soap->user)

    {

        delete (Service1SoapProxy*)soap->user;

    }

}

 

void JCSoapManager::Destory()

{

    if (m_pSoapProxy)

    {

        delete m_pSoapProxy;

        m_pSoapProxy = NULL;

    }

}

這些是初始化和釋放的代碼,初始化採用靜態函數,因此可以只需初始化一次。提供兩種釋放方式,一種由管理類釋放。一種通過靜態調用,傳入實體類的soap釋放,因爲這種方式可以不用一直保留管理類。

    下面是使用代碼:

    JCSoapManager::InitSoapUrl("http://localhost:15778/Service1.asmx");

    PersonUser pu;

    ns1__Person* pPerson = pu.GetPerson("1",3000.01);

   

    printf("姓名:%s  年齡:%d  工資:%.2f\n",pPerson->Name,pPerson->Age,pPerson->Salary);

    pu.Destory();//內存釋放

    //JCSoapManager::Destory(pPerson->soap);//第二種內存釋放方式  這種方式釋放以後JCSoapManager實例對象不能再次使用

    printf("人數:%d\n",pu.GetPersonNumber());

 

運行結果:

 

提供源代碼:https://download.csdn.net/download/u011736517/12242087

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章