如果您了解 C++ 语言,该函数的 SDK 文档几乎会告诉您您需要了解的所有内容:
- 您将包含您的 URL 的 C 风格的以 nul 结尾的字符串传递给它。
- 您将它的指针传递给缓冲区以接收输出字符串。
- 您向它传递一个或多个自定义函数行为的标志。
- 最后,它会返回一个
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
,然后使用地址运算符 ( &
) 向函数传递指向该变量的指针。现在,您正在传递函数垃圾,所以它失败了。
您正在使用 C 风格的字符串,在 C++ 代码中应该避免使用这种字符串。使用 C++ 字符串类(std::wstring
用于 Windows 代码),它是异常安全的并为您管理内存。如您所知,c_str()
成员函数使您可以轻松访问所有 C API 想要的 C 风格的以 nul 结尾的字符串。这很好用,您不需要自己使用原始字符数组。new
尽可能避免。
第三个问题可能是您尝试使用 C++ 字符串类型std::string
而不是std::wstring
. 前者是 8 位字符串类型,在 Windows 环境下不支持 Unicode。你想要std::wstring
,这是一个支持 Unicode 的宽字符串。如果您UNICODE
为项目定义了符号(默认情况下),这就是所有 Windows API 函数所期望的。