2013-08-16 3 views
0
HRESULT UrlCanonicalize(
    _In_  PCTSTR pszUrl, 
    _Out_ PTSTR pszCanonicalized, 
    _Inout_ DWORD *pcchCanonicalized, 
    DWORD dwFlags 
); 

Пример:Как я могу правильно назвать функцию API UrlCanonicalize?

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.

+1

Почему вы не показываете кулак, что вы пробовали? –

+0

@ MariusBancila-> Можете ли вы дать фрагмент кода для этой функции? – Rono

+1

Это было бы гораздо более образовательным для вас, чтобы показать нам, какой код вы пробовали. Таким образом, мы можем сказать вам, почему * это не сработало и как это исправить. Вы не можете ничего научиться, копируя и вставляя код других людей. –

ответ

2

Если вы знаете язык 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; 

код, который вы пытались есть несколько проблем:

  1. Вы неправильно инициализировали переменную dwCount. Функция хочет указатель, но это не значит, что вы должны объявить переменную как указатель. Вы также не хотите массив; это значение DWORD. Поэтому вам нужно объявить его как обычный DWORD, а затем использовать адрес-оператора (&), чтобы передать функцию указателю на эту переменную. Прямо сейчас, вы передаете мусор функции, так что он терпит неудачу.

  2. Вы используете строки стиля 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, определенный для вашего проекта (который он по умолчанию).

+0

-> Хорошо объяснил, вы великолепны для поддержки. – Rono

+0

У меня небольшая проблема с вышеупомянутым решением, мой url не закодирован после вызова UrlCanonicalize api – Rono

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.

+0

Thx dude действительно полезный – Rono

Смежные вопросы