HRESULT UrlCanonicalize(
_In_ PCTSTR pszUrl,
_Out_ PTSTR pszCanonicalized,
_Inout_ DWORD *pcchCanonicalized,
DWORD dwFlags
);
示例:
LPCTSTR pszURL = URL.c_str();
LPSTR pszOutPut = new CHAR[ strUrl.length ];
DWORD* dwCount = new DWORD[ strUrl.length ];
hRes = UrlCanonicalize( pszURL, pszOutPut,dwCount, URL_ESCAPE_UNSAFE );
输出:
E_INVALIDARG
每次尝试调用此API时,此API都会失败并返回E_INVALIDARG
。请给我一个工作代码段来调用UrlCanonicalize
函数。
答案 0 :(得分:2)
如果您了解C ++语言,the SDK documentation for the function几乎可以告诉您需要了解的所有内容:
HRESULT
值,这是一个错误代码。如果成功,该值将为S_OK
。如果失败,则会出现其他一些错误代码。它的工作原理如下:
std::wstring originalURL(L"http://www.example.com/hello/cruel/../world/");
// Allocate a buffer of the appropriate length.
// It needs to be at least as long as the input string.
std::wstring canonicalURL(originalURL.length() + 1, L'\0');
DWORD length = originalURL.length() + 1;
// Call the function to modify the string.
HRESULT hr = UrlCanonicalize(originalURL.c_str(), // input string
&canonicalURL[0], // buffer
&length, // pointer to a DWORD that contains the length of the buffer
URL_UNESCAPE | URL_ESCAPE_UNSAFE);
if (SUCCEEDED(hr))
{
// The function succeeded.
// Your canonicalized URL is in the canonicalURL string.
MessageBox(nullptr, canonicalURL.c_str(), L"The URL is:", MB_OK);
}
else
{
// The function failed.
// The hr variable contains the error code.
throw std::runtime_error("The UrlCanonicalize function failed.");
}
如果要确保缓冲区足够长(并且避免必须处理该错误),请在分配时使用常量INTERNET_MAX_URL_LENGTH
(在WinInet.h
中声明):
std::wstring canonicalURL(INTERNET_MAX_URL_LENGTH, L'\0');
DWORD length = INTERNET_MAX_URL_LENGTH;
您尝试的代码有几个问题:
您错误地初始化了dwCount
变量。该函数需要一个指针,但这并不意味着您应该将该变量声明为指针。你也不想要阵列;这是一个DWORD
值。因此,您需要将其声明为常规DWORD
,然后使用address-of运算符(&
)将函数传递给该变量。现在,你正在传递函数垃圾,所以它失败了。
您正在使用C风格的字符串,您应该避免使用C ++代码。使用C ++字符串类(Windows代码为std::wstring
),这是异常安全的并为您管理内存。如您所知,c_str()
成员函数使您可以像所有C API所需的那样轻松访问C样式的以空字符串结尾的字符串。这很好用,你不需要自己使用原始字符数组。尽可能避免使用new
。
可能第三个问题是您尝试使用C ++字符串类型std::string
而不是std::wstring
。前者是8位字符串类型,在Windows环境中不支持Unicode。您需要std::wstring
,这是一个支持Unicode的宽字符串。如果您为项目定义了UNICODE
符号(默认情况下是这样),那么这就是所有Windows API函数所期望的。
答案 1 :(得分:0)
你走了:
LPCTSTR pszURL = URL.c_str();
DWORD nOutputLength = strUrl.length * 2 + 32;
LPTSTR pszOutPut = new TCHAR[nOutputLength];
hRes = UrlCanonicalize( pszURL, pszOutPut, &nOutputLength, URL_ESCAPE_UNSAFE);
在第三个参数上,您提供了垃圾而不是指向初始化值的指针,因此您有API故障。 MSDN has it all适合您:
指向一个值的指针,该值在输入时设置为pszCanonicalized缓冲区中的字符数。