一道面试题-Web Service方面的

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

 1 //创建连接到IP866的web服务 
 2 WebService::CWebService * web = new WebService::CWebService ; 
 3 
 4         //省略部份代码 
 5 
 6 //反查IP,参数(用户密钥,IP或域名地址,BSTR指针,数组长度) 
 7 if(  web->ReverseIP( bstr_key , bstr_text  ,&bstr,&len ) == S_OK ) 
 8 { 
 9 
10         //省略部份代码 
11 
12 
13 for  (int  i=0;i <  len;i++)  
14 {  
15   CComBSTR domain = *bstr++ ; 
16   m_listbox.AddString(  (LPCTSTR)domain  ); //m_listbox是一个列表控件 
17   
18 }  
19         } 
20 
21 delete web; 

 

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

生成的代理类:

  1 myWeb.h
  2 
  3 //
  4 // sproxy.exe generated file
  5 // do not modify this file
  6 //
  7 // Created: 06/24/2009@13:41:19
  8 //
  9 
 10 #pragma once
 11 
 12 
 13 #if !defined(_WIN32_WINDOWS) && !defined(_WIN32_WINNT) && !defined(_WIN32_WCE)
 14 #pragma message("warning: defining _WIN32_WINDOWS = 0x0410")
 15 #define _WIN32_WINDOWS 0x0410
 16 #endif
 17 
 18 #include <atlsoap.h>
 19 
 20 namespace WebService
 21 {
 22 
 23 template <typename TClient = CSoapSocketClientT<> >
 24 class CWebServiceT : 
 25  public TClient, 
 26  public CSoapRootHandler
 27 {
 28 protected:
 29 
 30  const _soapmap ** GetFunctionMap();
 31  const _soapmap ** GetHeaderMap();
 32  void * GetHeaderValue();
 33  const wchar_t * GetNamespaceUri();
 34  const char * GetServiceName();
 35  const char * GetNamespaceUriA();
 36  HRESULT CallFunction(
 37   void *pvParam, 
 38   const wchar_t *wszLocalName, int cchLocalName,
 39   size_t nItem);
 40  HRESULT GetClientReader(ISAXXMLReader **ppReader);
 41 
 42 public:
 43 
 44  HRESULT __stdcall QueryInterface(REFIID riid, void **ppv)
 45  {
 46   if (ppv == NULL)
 47   {
 48    return E_POINTER;
 49   }
 50 
 51   *ppv = NULL;
 52 
 53   if (InlineIsEqualGUID(riid, IID_IUnknown) ||
 54    InlineIsEqualGUID(riid, IID_ISAXContentHandler))
 55   {
 56    *ppv = static_cast<ISAXContentHandler *>(this);
 57    return S_OK;
 58   }
 59 
 60   return E_NOINTERFACE;
 61  }
 62 
 63  ULONG __stdcall AddRef()
 64  {
 65   return 1;
 66  }
 67 
 68  ULONG __stdcall Release()
 69  {
 70   return 1;
 71  }
 72 
 73  CWebServiceT(ISAXXMLReader *pReader = NULL)
 74   :TClient(_T("http://www.ip866.com/WebService.asmx"))
 75  {
 76   SetClient(true);
 77   SetReader(pReader);
 78  }
 79  
 80  ~CWebServiceT()
 81  {
 82   Uninitialize();
 83  }
 84  
 85  void Uninitialize()
 86  {
 87   UninitializeSOAP();
 88  } 
 89 
 90  HRESULT ReverseIP(
 91   BSTR userkey, 
 92   BSTR reverseText, 
 93   BSTR** ReverseIPResult, int* ReverseIPResult_nSizeIs
 94  );
 95 };
 96 
 97 typedef CWebServiceT<> CWebService;
 98 
 99 struct __CWebService_ReverseIP_struct
100 {
101  BSTR userkey;
102  BSTR reverseText;
103  BSTR *ReverseIPResult;
104  int __ReverseIPResult_nSizeIs;
105 };
106 
107 extern __declspec(selectany) const _soapmapentry __CWebService_ReverseIP_entries[] =
108 {
109 
110  {
111   0x42030748, 
112   "userkey", 
113   L"userkey", 
114   sizeof("userkey")-1, 
115   SOAPTYPE_STRING, 
116   SOAPFLAG_NONE | SOAPFLAG_IN | SOAPFLAG_PID | SOAPFLAG_DOCUMENT | SOAPFLAG_LITERAL | SOAPFLAG_NULLABLE,
117   offsetof(__CWebService_ReverseIP_struct, userkey),
118   NULL,
119   NULL,
120   -1,
121  },
122  {
123   0x3DCCD2C1, 
124   "reverseText", 
125   L"reverseText", 
126   sizeof("reverseText")-1, 
127   SOAPTYPE_STRING, 
128   SOAPFLAG_NONE | SOAPFLAG_IN | SOAPFLAG_PID | SOAPFLAG_DOCUMENT | SOAPFLAG_LITERAL | SOAPFLAG_NULLABLE,
129   offsetof(__CWebService_ReverseIP_struct, reverseText),
130   NULL,
131   NULL,
132   -1,
133  },
134  {
135   0xEFCF09D4, 
136   "ReverseIPResult", 
137   L"ReverseIPResult", 
138   sizeof("ReverseIPResult")-1, 
139   SOAPTYPE_STRING, 
140   SOAPFLAG_NONE | SOAPFLAG_OUT | SOAPFLAG_DYNARR | SOAPFLAG_PID | SOAPFLAG_DOCUMENT | SOAPFLAG_LITERAL | SOAPFLAG_NULLABLE,
141   offsetof(__CWebService_ReverseIP_struct, ReverseIPResult),
142   NULL,
143   NULL,
144   2+1,
145  },
146  {
147   0xEFCF09D4,
148   "__ReverseIPResult_nSizeIs",
149   L"__ReverseIPResult_nSizeIs",
150   sizeof("__ReverseIPResult_nSizeIs")-1,
151   SOAPTYPE_INT,
152   SOAPFLAG_NOMARSHAL,
153   offsetof(__CWebService_ReverseIP_struct, __ReverseIPResult_nSizeIs),
154   NULL,
155   NULL,
156   -1
157  },
158  { 0x00000000 }
159 };
160 
161 extern __declspec(selectany) const _soapmap __CWebService_ReverseIP_map =
162 {
163  0x1F5FEF24,
164  "ReverseIP",
165  L"ReverseIPResponse",
166  sizeof("ReverseIP")-1,
167  sizeof("ReverseIPResponse")-1,
168  SOAPMAP_FUNC,
169  __CWebService_ReverseIP_entries,
170  sizeof(__CWebService_ReverseIP_struct),
171  1,
172  -1,
173  SOAPFLAG_NONE | SOAPFLAG_PID | SOAPFLAG_DOCUMENT | SOAPFLAG_LITERAL,
174  0xC2E575C3,
175  "http://tempuri.org/",
176  L"http://tempuri.org/",
177  sizeof("http://tempuri.org/%22)-1
178 };
179 
180 extern __declspec(selectany) const _soapmap * __CWebService_funcs[] =
181 {
182  &__CWebService_ReverseIP_map,
183  NULL
184 };
185 
186 template <typename TClient>
187 inline HRESULT CWebServiceT<TClient>::ReverseIP(
188   BSTR userkey, 
189   BSTR reverseText, 
190   BSTR** ReverseIPResult, int* __ReverseIPResult_nSizeIs
191  )
192 {
193     if ( ReverseIPResult == NULL )
194   return E_POINTER;
195  if( __ReverseIPResult_nSizeIs == NULL )
196   return E_POINTER;
197 
198  HRESULT __atlsoap_hr = InitializeSOAP(NULL);
199  if (FAILED(__atlsoap_hr))
200  {
201   SetClientError(SOAPCLIENT_INITIALIZE_ERROR);
202   return __atlsoap_hr;
203  }
204  
205  CleanupClient();
206 
207  CComPtr<IStream> __atlsoap_spReadStream;
208  __CWebService_ReverseIP_struct __params;
209  memset(&__params, 0x00, sizeof(__params));
210  __params.userkey = userkey;
211  __params.reverseText = reverseText;
212 
213  __atlsoap_hr = SetClientStruct(&__params, 0);
214  if (FAILED(__atlsoap_hr))
215  {
216   SetClientError(SOAPCLIENT_OUTOFMEMORY);
217   goto __skip_cleanup;
218  }
219  
220  __atlsoap_hr = GenerateResponse(GetWriteStream());
221  if (FAILED(__atlsoap_hr))
222  {
223   SetClientError(SOAPCLIENT_GENERATE_ERROR);
224   goto __skip_cleanup;
225  }
226  
227  __atlsoap_hr = SendRequest(_T("SOAPAction: \"http://tempuri.org/ReverseIP/%22/r/n"));
228  if (FAILED(__atlsoap_hr))
229  {
230   goto __skip_cleanup;
231  }
232  __atlsoap_hr = GetReadStream(&__atlsoap_spReadStream);
233  if (FAILED(__atlsoap_hr))
234  {
235   SetClientError(SOAPCLIENT_READ_ERROR);
236   goto __skip_cleanup;
237  }
238  
239  // cleanup any in/out-params and out-headers from previous calls
240  Cleanup();
241  __atlsoap_hr = BeginParse(__atlsoap_spReadStream);
242  if (FAILED(__atlsoap_hr))
243  {
244   SetClientError(SOAPCLIENT_PARSE_ERROR);
245   goto __cleanup;
246  }
247 
248  *ReverseIPResult = __params.ReverseIPResult;
249  *__ReverseIPResult_nSizeIs = __params.__ReverseIPResult_nSizeIs;
250  goto __skip_cleanup;
251  
252 __cleanup:
253  Cleanup();
254 __skip_cleanup:
255  ResetClientState(true);
256  memset(&__params, 0x00, sizeof(__params));
257  return __atlsoap_hr;
258 }
259 
260 template <typename TClient>
261 ATL_NOINLINE inline const _soapmap ** CWebServiceT<TClient>::GetFunctionMap()
262 {
263  return __CWebService_funcs;
264 }
265 
266 template <typename TClient>
267 ATL_NOINLINE inline const _soapmap ** CWebServiceT<TClient>::GetHeaderMap()
268 {
269  static const _soapmapentry __CWebService_ReverseIP_atlsoapheader_entries[] =
270  {
271   { 0x00000000 }
272  };
273 
274  static const _soapmap __CWebService_ReverseIP_atlsoapheader_map = 
275  {
276   0x1F5FEF24,
277   "ReverseIP",
278   L"ReverseIPResponse",
279   sizeof("ReverseIP")-1,
280   sizeof("ReverseIPResponse")-1,
281   SOAPMAP_HEADER,
282   __CWebService_ReverseIP_atlsoapheader_entries,
283   0,
284   0,
285   -1,
286   SOAPFLAG_NONE | SOAPFLAG_PID | SOAPFLAG_DOCUMENT | SOAPFLAG_LITERAL,
287   0xC2E575C3,
288   "http://tempuri.org/",
289   L"http://tempuri.org/",
290   sizeof("http://tempuri.org/%22)-1
291  };
292 
293 
294  static const _soapmap * __CWebService_headers[] =
295  {
296   &__CWebService_ReverseIP_atlsoapheader_map,
297   NULL
298  };
299  
300  return __CWebService_headers;
301 }
302 
303 template <typename TClient>
304 ATL_NOINLINE inline void * CWebServiceT<TClient>::GetHeaderValue()
305 {
306  return this;
307 }
308 
309 template <typename TClient>
310 ATL_NOINLINE inline const wchar_t * CWebServiceT<TClient>::GetNamespaceUri()
311 {
312  return L"http://tempuri.org/";
313 }
314 
315 template <typename TClient>
316 ATL_NOINLINE inline const char * CWebServiceT<TClient>::GetServiceName()
317 {
318  return NULL;
319 }
320 
321 template <typename TClient>
322 ATL_NOINLINE inline const char * CWebServiceT<TClient>::GetNamespaceUriA()
323 {
324  return "http://tempuri.org/";
325 }
326 
327 template <typename TClient>
328 ATL_NOINLINE inline HRESULT CWebServiceT<TClient>::CallFunction(
329  void *, 
330  const wchar_t *, int,
331  size_t)
332 {
333  return E_NOTIMPL;
334 }
335 
336 template <typename TClient>
337 ATL_NOINLINE inline HRESULT CWebServiceT<TClient>::GetClientReader(ISAXXMLReader **ppReader)
338 {
339  if (ppReader == NULL)
340  {
341   return E_INVALIDARG;
342  }
343  
344  CComPtr<ISAXXMLReader> spReader = GetReader();
345  if (spReader.p != NULL)
346  {
347   *ppReader = spReader.Detach();
348   return S_OK;
349  }
350  return TClient::GetClientReader(ppReader);
351 }
352 
353 } // namespace WebService
354 
355 
356 在引用文件里:
357 
358 
359 #include "myWeb.h"
360 
361 using namespace  WebService;
362 
363 void CWebTestDlg::OnBnClickedBtnConn()
364 {
365  // TODO: Add your control notification handler code here
366  CoInitialize(NULL);
367 
368  //创建连接到IP866的web服务
369  CWebServiceT<CSoapSocketClientT<>>* web = new CWebServiceT<CSoapSocketClientT<>>();
370  BSTR* bstr = NULL; 
371  int len = 0;
372 
373  //省略部份代码
374  CString strKey = _T("001");
375  CString strText = _T("115.192.211.98");
376 
377  CComBSTR bstr_Key = strKey.AllocSysString();
378  CComBSTR bstr_Text = strText.AllocSysString();
379 
380  //省略部份代码
381 
382  
383  //反查IP,参数(用户密钥,IP或域名地址,BSTR指针,数组长度)
384  HRESULT hResult = web->ReverseIP(bstr_Key, bstr_Text, &bstr, &len);
385  if( hResult == S_OK)
386  {
387 
388   //省略部份代码
389   for(int i = 0; i < len; i++)
390   {      
391    _bstr_t tempStr(bstr[i], FALSE);
392    m_ctlListBox.AddString(tempStr);
393 
394    //CComBSTR domain = *(bstr++);
395    //CString strDomain;
396    //domain.CopyTo(strDomain);
397    //m_ctlListBox.AddString((LPCTSTR)domain); //m_listbox是一个列表控件
398   }   
399  }
400 
401  if (bstr != NULL)
402  {
403   delete bstr;
404  } 
405  
406  if (web != NULL)
407  {
408   delete web;
409  }
410  
411 
412  CoUninitialize();
413 
414  return;
415 }

 


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

posted @ 2009-07-20 16:39  vsignsoft  阅读(3995)  评论(11)    收藏  举报