2016-12-31 2 views
0

Недавно я сделал клиент обновлений для своего программного обеспечения. Он использует WinHTTP для подключения к серверу моей компании, я хотел добавить специальную строку в разделе user-agent API WINDOWS в WinHttpOpen. Мне нужно передать переменную в pwszUserAgent из WinHttpOpen, которая является LPCWSTR.Передача переменной в WIN32 API LPCWSTR?

Вот часть моего кода

//convert string to wstring 
wstring s2ws(const string& s) 
{ 
    int len; 
    int slength = (int)s.length() + 1; 
    len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0); 
    wchar_t* buf = new wchar_t[len]; 
    MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len); 
    wstring r(buf); 
    delete[] buf; 
    return r; 
} 


//This defined string indicates a string variable I got previously 
string MyVariable_grabbed_previously = "version:15.3, Date:2016/12/10" 
//a flag indicate if version string variable exists 
bool Version_variable = TRUE; 

//define LPCWSTR for winAPI user-agent section 
LPCWSTR UserAgent; 

if (Version_variable) { 
//version variable exist 
     string UA = "my custom UA & version" + MyVariable_grabbed_previously; 
     wstring UAWS = s2ws(UA); 
     UserAgent = UAWS.c_str(); 



    } 
    else { 
//Version variable not exist 
     UserAgent = L"my custom UA"; 

    } 


hSession = WinHttpOpen(UserAgent, WINHTTP_ACCESS_TYPE_NO_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); 

Однако, кажется, моя программа хранится, используя пустую строку в качестве агента пользователя, я задаюсь вопросом, почему мое значение не может быть передано правильно? Я новичок в Windows API.

+0

в 's2ws' вы возвращаете локальный объект' wstring г ', который будет уничтожен при выходе функции - так это ошибка кода' C++ ', не связанная с winapi. ваш код с 'WinHttpOpen (L" мой пользовательский UA ",' работал? – RbMm

+1

@RbMm Нет. Это не так. Возврат wstring в порядке. Сделана копия или даже пропущена с RVO –

+0

мой код WinHttpOpen (L "мой пользовательский UA "действительно работал –

ответ

3

Проблема в том, что вы передаете недействительный указатель на WinHttpOpen(). Вы создаете объект временноstd::wstring, захватывая указатель на его данные, а затем передавая этот указатель послеstd::wstring уничтожен.

Измените UserAgent переменную std::wstring вместо, а затем использовать c_str(), когда вы будете готовы передать его, например:

wstring s2ws(const string& s) 
{ 
    wstring r; 
    int slength = s.length(); 
    if (slength > 0) 
    { 
     int len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0); 
     r.resize(len); 
     MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, &r[0], len);   
    } 
    return r; 
} 

string MyVariable_grabbed_previously = "version:15.3, Date:2016/12/10"; 
bool Version_variable = true;  
wstring UserAgent; 

... 

if (Version_variable) { 
    UserAgent = s2ws("my custom UA & " + MyVariable_grabbed_previously); 
} 
else { 
    UserAgent = L"my custom UA"; 
} 

/* Alternatively: 
UserAgent = L"my custom UA"; 
if (Version_variable) { 
    UserAgent += (L" & " + s2ws(MyVariable_grabbed_previously)); 
} 
*/ 

hSession = WinHttpOpen(UserAgent.c_str(), WINHTTP_ACCESS_TYPE_NO_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); 
+0

Это лучший ответ, лучше, чем другое решение, с которым я пришел, спасибо :) –

+0

Код использует исключения, но не является исключением. Необработанный указатель 'buf' не будет удален, если c'tor для' r' выдает исключение. 'buf' должен либо управляться объектом с автоматической продолжительностью хранения (например,' std :: string'), либо должен быть назначен интеллектуальному указателю с соответствующим делетером. – IInspectable

+0

Кроме того, 'wstring r (buf, len);' строит строковый объект, содержащий конечный нулевой терминатор. Хотя обычно это не фатальная ошибка, строки со встроенными символами NUL могут привести к неожиданному поведению. – IInspectable