如何正确调用 UrlCanonicalize API 函数
How do I call the UrlCanonicalize API function correctly?
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 失败,每次我尝试调用它时都会返回E_INVALIDARG
。请给我一个工作代码片段来调用UrlCanonicalize
函数。
如果您了解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' ');
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' ');
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 的宽字符串。这是所有 Windows API 函数所期望的,如果你为项目定义了UNICODE
符号(默认情况下是(。
你来了:
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 为您提供了一切:
指向一个值的指针,该值在输入时设置为 pszCanonicalized 缓冲区中的字符数。
- 调用 Win32 API 函数时未定义的引用
- 谁拥有作为指向 Windows API 函数的指针传递的值?
- 将uint8_t*buffer和size_tbufferlen从C++传递到C中的API函数的最佳方式是什么
- 如何在应用程序正在运行的系统上查看所需的Windows API函数
- 我的 API 函数应该shared_ptr还是weak_ptr
- 将 API 函数参数从 'char *' 更改为"const char *"有哪些潜在问题?
- 当涉及数组时,我们是否可以安全地从C++调用C API函数
- 从 Windows KMD 调用用户空间 API 函数
- 写入const API函数(C )中的成员变量
- 毒害某些API函数(不是维护者)
- win32 API 函数 GetModuleFileName 或 GetModuleHandle 中的"Module"是什么?
- 将指针传递给API函数
- 如何通过重用单个API函数来调用不同的操作
- 将 ASCII 字符串转换为 UTF-16,然后再将它们传递给 Windows API 函数
- POSIX 或 Linux API 函数,用于从路径获取文件扩展名
- 如何正确调用 UrlCanonicalize API 函数
- 找不到Win32 API函数
- 将 AfxGetInstanceHandle() 的调用替换为 Windows API 函数
- 包装任何API函数
- Windows API函数不可用,但它应该可用