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