上篇文章使用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