一道面试题-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 造成内存泄漏的。

浙公网安备 33010602011771号