一道面试题-Web Service方面的

问:以下代码,都有什么问题,而且,有内存泄漏,要求纠正之。
并且,不许用.net知识,只能用纯C++方面的知识。
里面,还附加了几个网址,我已经忘掉了。

//创建连接到IP866的web服务
WebService::CWebService * web = new WebService::CWebService ;

        //省略部份代码

//反查IP,参数(用户密钥,IP或域名地址,BSTR指针,数组长度)
if(  web->ReverseIP( bstr_key , bstr_text  ,&bstr,&len ) == S_OK )
{

        //省略部份代码


for  (int  i=0;i <  len;i++) 

  CComBSTR domain = *bstr++ ;
  m_listbox.AddString(  (LPCTSTR)domain  ); //m_listbox是一个列表控件
 

        }

delete web;
--------------------------------------------
解答:
其实,就是到他提供的一个链接地址,去下载 ATL_Server_Source_and_Headers_9_0_70425_Alpha.zip,下载下来的工具是源代码,你需要build SProxy一下,然后,利用之生产web service的一个代理class。
再利用这个代理class,就OK了。

生成的代理类:
myWeb.h

//
// sproxy.exe generated file
// do not modify this file
//
// Created: 06/24/2009@13:41:19
//

#pragma once


#if !defined(_WIN32_WINDOWS) && !defined(_WIN32_WINNT) && !defined(_WIN32_WCE)
#pragma message("warning: defining _WIN32_WINDOWS = 0x0410")
#define _WIN32_WINDOWS 0x0410
#endif

#include <atlsoap.h>

namespace WebService
{

template <typename TClient = CSoapSocketClientT<> >
class CWebServiceT :
 public TClient,
 public CSoapRootHandler
{
protected:

 const _soapmap ** GetFunctionMap();
 const _soapmap ** GetHeaderMap();
 void * GetHeaderValue();
 const wchar_t * GetNamespaceUri();
 const char * GetServiceName();
 const char * GetNamespaceUriA();
 HRESULT CallFunction(
  void *pvParam,
  const wchar_t *wszLocalName, int cchLocalName,
  size_t nItem);
 HRESULT GetClientReader(ISAXXMLReader **ppReader);

public:

 HRESULT __stdcall QueryInterface(REFIID riid, void **ppv)
 {
  if (ppv == NULL)
  {
   return E_POINTER;
  }

  *ppv = NULL;

  if (InlineIsEqualGUID(riid, IID_IUnknown) ||
   InlineIsEqualGUID(riid, IID_ISAXContentHandler))
  {
   *ppv = static_cast<ISAXContentHandler *>(this);
   return S_OK;
  }

  return E_NOINTERFACE;
 }

 ULONG __stdcall AddRef()
 {
  return 1;
 }

 ULONG __stdcall Release()
 {
  return 1;
 }

 CWebServiceT(ISAXXMLReader *pReader = NULL)
  :TClient(_T("http://www.ip866.com/WebService.asmx"))
 {
  SetClient(true);
  SetReader(pReader);
 }
 
 ~CWebServiceT()
 {
  Uninitialize();
 }
 
 void Uninitialize()
 {
  UninitializeSOAP();
 } 

 HRESULT ReverseIP(
  BSTR userkey,
  BSTR reverseText,
  BSTR** ReverseIPResult, int* ReverseIPResult_nSizeIs
 );
};

typedef CWebServiceT<> CWebService;

struct __CWebService_ReverseIP_struct
{
 BSTR userkey;
 BSTR reverseText;
 BSTR *ReverseIPResult;
 int __ReverseIPResult_nSizeIs;
};

extern __declspec(selectany) const _soapmapentry __CWebService_ReverseIP_entries[] =
{

 {
  0x42030748,
  "userkey",
  L"userkey",
  sizeof("userkey")-1,
  SOAPTYPE_STRING,
  SOAPFLAG_NONE | SOAPFLAG_IN | SOAPFLAG_PID | SOAPFLAG_DOCUMENT | SOAPFLAG_LITERAL | SOAPFLAG_NULLABLE,
  offsetof(__CWebService_ReverseIP_struct, userkey),
  NULL,
  NULL,
  -1,
 },
 {
  0x3DCCD2C1,
  "reverseText",
  L"reverseText",
  sizeof("reverseText")-1,
  SOAPTYPE_STRING,
  SOAPFLAG_NONE | SOAPFLAG_IN | SOAPFLAG_PID | SOAPFLAG_DOCUMENT | SOAPFLAG_LITERAL | SOAPFLAG_NULLABLE,
  offsetof(__CWebService_ReverseIP_struct, reverseText),
  NULL,
  NULL,
  -1,
 },
 {
  0xEFCF09D4,
  "ReverseIPResult",
  L"ReverseIPResult",
  sizeof("ReverseIPResult")-1,
  SOAPTYPE_STRING,
  SOAPFLAG_NONE | SOAPFLAG_OUT | SOAPFLAG_DYNARR | SOAPFLAG_PID | SOAPFLAG_DOCUMENT | SOAPFLAG_LITERAL | SOAPFLAG_NULLABLE,
  offsetof(__CWebService_ReverseIP_struct, ReverseIPResult),
  NULL,
  NULL,
  2+1,
 },
 {
  0xEFCF09D4,
  "__ReverseIPResult_nSizeIs",
  L"__ReverseIPResult_nSizeIs",
  sizeof("__ReverseIPResult_nSizeIs")-1,
  SOAPTYPE_INT,
  SOAPFLAG_NOMARSHAL,
  offsetof(__CWebService_ReverseIP_struct, __ReverseIPResult_nSizeIs),
  NULL,
  NULL,
  -1
 },
 { 0x00000000 }
};

extern __declspec(selectany) const _soapmap __CWebService_ReverseIP_map =
{
 0x1F5FEF24,
 "ReverseIP",
 L"ReverseIPResponse",
 sizeof("ReverseIP")-1,
 sizeof("ReverseIPResponse")-1,
 SOAPMAP_FUNC,
 __CWebService_ReverseIP_entries,
 sizeof(__CWebService_ReverseIP_struct),
 1,
 -1,
 SOAPFLAG_NONE | SOAPFLAG_PID | SOAPFLAG_DOCUMENT | SOAPFLAG_LITERAL,
 0xC2E575C3,
 "http://tempuri.org/",
 L"http://tempuri.org/",
 sizeof("http://tempuri.org/%22)-1
};

extern __declspec(selectany) const _soapmap * __CWebService_funcs[] =
{
 &__CWebService_ReverseIP_map,
 NULL
};

template <typename TClient>
inline HRESULT CWebServiceT<TClient>::ReverseIP(
  BSTR userkey,
  BSTR reverseText,
  BSTR** ReverseIPResult, int* __ReverseIPResult_nSizeIs
 )
{
    if ( ReverseIPResult == NULL )
  return E_POINTER;
 if( __ReverseIPResult_nSizeIs == NULL )
  return E_POINTER;

 HRESULT __atlsoap_hr = InitializeSOAP(NULL);
 if (FAILED(__atlsoap_hr))
 {
  SetClientError(SOAPCLIENT_INITIALIZE_ERROR);
  return __atlsoap_hr;
 }
 
 CleanupClient();

 CComPtr<IStream> __atlsoap_spReadStream;
 __CWebService_ReverseIP_struct __params;
 memset(&__params, 0x00, sizeof(__params));
 __params.userkey = userkey;
 __params.reverseText = reverseText;

 __atlsoap_hr = SetClientStruct(&__params, 0);
 if (FAILED(__atlsoap_hr))
 {
  SetClientError(SOAPCLIENT_OUTOFMEMORY);
  goto __skip_cleanup;
 }
 
 __atlsoap_hr = GenerateResponse(GetWriteStream());
 if (FAILED(__atlsoap_hr))
 {
  SetClientError(SOAPCLIENT_GENERATE_ERROR);
  goto __skip_cleanup;
 }
 
 __atlsoap_hr = SendRequest(_T("SOAPAction: \"http://tempuri.org/ReverseIP/%22/r/n"));
 if (FAILED(__atlsoap_hr))
 {
  goto __skip_cleanup;
 }
 __atlsoap_hr = GetReadStream(&__atlsoap_spReadStream);
 if (FAILED(__atlsoap_hr))
 {
  SetClientError(SOAPCLIENT_READ_ERROR);
  goto __skip_cleanup;
 }
 
 // cleanup any in/out-params and out-headers from previous calls
 Cleanup();
 __atlsoap_hr = BeginParse(__atlsoap_spReadStream);
 if (FAILED(__atlsoap_hr))
 {
  SetClientError(SOAPCLIENT_PARSE_ERROR);
  goto __cleanup;
 }

 *ReverseIPResult = __params.ReverseIPResult;
 *__ReverseIPResult_nSizeIs = __params.__ReverseIPResult_nSizeIs;
 goto __skip_cleanup;
 
__cleanup:
 Cleanup();
__skip_cleanup:
 ResetClientState(true);
 memset(&__params, 0x00, sizeof(__params));
 return __atlsoap_hr;
}

template <typename TClient>
ATL_NOINLINE inline const _soapmap ** CWebServiceT<TClient>::GetFunctionMap()
{
 return __CWebService_funcs;
}

template <typename TClient>
ATL_NOINLINE inline const _soapmap ** CWebServiceT<TClient>::GetHeaderMap()
{
 static const _soapmapentry __CWebService_ReverseIP_atlsoapheader_entries[] =
 {
  { 0x00000000 }
 };

 static const _soapmap __CWebService_ReverseIP_atlsoapheader_map =
 {
  0x1F5FEF24,
  "ReverseIP",
  L"ReverseIPResponse",
  sizeof("ReverseIP")-1,
  sizeof("ReverseIPResponse")-1,
  SOAPMAP_HEADER,
  __CWebService_ReverseIP_atlsoapheader_entries,
  0,
  0,
  -1,
  SOAPFLAG_NONE | SOAPFLAG_PID | SOAPFLAG_DOCUMENT | SOAPFLAG_LITERAL,
  0xC2E575C3,
  "http://tempuri.org/",
  L"http://tempuri.org/",
  sizeof("http://tempuri.org/%22)-1
 };


 static const _soapmap * __CWebService_headers[] =
 {
  &__CWebService_ReverseIP_atlsoapheader_map,
  NULL
 };
 
 return __CWebService_headers;
}

template <typename TClient>
ATL_NOINLINE inline void * CWebServiceT<TClient>::GetHeaderValue()
{
 return this;
}

template <typename TClient>
ATL_NOINLINE inline const wchar_t * CWebServiceT<TClient>::GetNamespaceUri()
{
 return L"http://tempuri.org/";
}

template <typename TClient>
ATL_NOINLINE inline const char * CWebServiceT<TClient>::GetServiceName()
{
 return NULL;
}

template <typename TClient>
ATL_NOINLINE inline const char * CWebServiceT<TClient>::GetNamespaceUriA()
{
 return "http://tempuri.org/";
}

template <typename TClient>
ATL_NOINLINE inline HRESULT CWebServiceT<TClient>::CallFunction(
 void *,
 const wchar_t *, int,
 size_t)
{
 return E_NOTIMPL;
}

template <typename TClient>
ATL_NOINLINE inline HRESULT CWebServiceT<TClient>::GetClientReader(ISAXXMLReader **ppReader)
{
 if (ppReader == NULL)
 {
  return E_INVALIDARG;
 }
 
 CComPtr<ISAXXMLReader> spReader = GetReader();
 if (spReader.p != NULL)
 {
  *ppReader = spReader.Detach();
  return S_OK;
 }
 return TClient::GetClientReader(ppReader);
}

} // namespace WebService


在引用文件里:


#include "myWeb.h"

using namespace  WebService;

void CWebTestDlg::OnBnClickedBtnConn()
{
 // TODO: Add your control notification handler code here
 CoInitialize(NULL);

 //创建连接到IP866的web服务
 CWebServiceT<CSoapSocketClientT<>>* web = new CWebServiceT<CSoapSocketClientT<>>();
 BSTR* bstr = NULL; 
 int len = 0;

 //省略部份代码
 CString strKey = _T("001");
 CString strText = _T("115.192.211.98");

 CComBSTR bstr_Key = strKey.AllocSysString();
 CComBSTR bstr_Text = strText.AllocSysString();

 //省略部份代码

 
 //反查IP,参数(用户密钥,IP或域名地址,BSTR指针,数组长度)
 HRESULT hResult = web->ReverseIP(bstr_Key, bstr_Text, &bstr, &len);
 if( hResult == S_OK)
 {

  //省略部份代码
  for(int i = 0; i < len; i++)
  {      
   _bstr_t tempStr(bstr[i], FALSE);
   m_ctlListBox.AddString(tempStr);

   //CComBSTR domain = *(bstr++);
   //CString strDomain;
   //domain.CopyTo(strDomain);
   //m_ctlListBox.AddString((LPCTSTR)domain); //m_listbox是一个列表控件
  }  
 }

 if (bstr != NULL)
 {
  delete bstr;
 } 
 
 if (web != NULL)
 {
  delete web;
 }
 

 CoUninitialize();

 return;
}


就是那个bstr 造成内存泄漏的。

你可能感兴趣的:(web Service)