二.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

 

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