问:以下代码,都有什么问题,而且,有内存泄漏,要求纠正之。
并且,不许用.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 造成内存泄漏的。