Если вы знаете язык C++, the SDK documentation for the function довольно много говорит вам все, что вам нужно знать:
- Вы передаёте в C-стиль NUL завершающей строку, содержащую ваш URL.
- Вы передаете указатель на буфер для получения выходной строки.
- Вы передаете ему один или несколько флагов, которые настраивают поведение функции.
- И, наконец, он возвращает вам значение
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, как и все C API-интерфейсы. Это прекрасно работает, вам не нужно использовать собственные массивы символов самостоятельно. Избегайте, если возможно, new
.
Потенциально, третья проблема заключается в том, что вы пытаетесь использовать C++ тип строки std::string
вместо std::wstring
. Первый - это 8-битный строковый тип и не поддерживает Unicode в среде Windows. Вы хотите std::wstring
, который является широкой строкой с поддержкой Unicode. Это то, что ожидают все функции Windows API, если у вас есть символ UNICODE
, определенный для вашего проекта (который он по умолчанию).
Почему вы не показываете кулак, что вы пробовали? –
@ MariusBancila-> Можете ли вы дать фрагмент кода для этой функции? – Rono
Это было бы гораздо более образовательным для вас, чтобы показать нам, какой код вы пробовали. Таким образом, мы можем сказать вам, почему * это не сработало и как это исправить. Вы не можете ничего научиться, копируя и вставляя код других людей. –