Скрытая строка в LPVOID и LPCWSTR в C ++ - PullRequest
0 голосов
/ 06 февраля 2010

Я работаю с WinHTTP API в c ++ и начал писать класс-оболочку для своего приложения. Для простоты у меня есть ряд функций, которые могут принимать строковые параметры и использовать их в вызовах winHTTP. Однако многие из них требуют, чтобы данные были LPVOID или LPCWSTR. Я могу заставить все это работать, заставляя мои функции-оболочки принимать параметры LPVOID или LPCWSTR, но я бы предпочел строковые параметры. Так есть ли способ перейти от жало к LPVOID / LPCWSTR?

Мои попытки (ниже) только что дали толчок

bool httpWrapper::setPostData(const string &postData){

 _postData = (LPVOID)postData.c_str();

 _postData_len = 47;

 return false;
}

Любая помощь будет высоко ценится

Спасибо

Ответы [ 4 ]

1 голос
/ 06 февраля 2010

Будьте осторожны с поведением c_str ().Символ *, который он возвращает, является временным, он станет недействительным после изменения или уничтожения строки.Что вполне может произойти до использования _postData, возможно, как только вернется setPostData ().Вам нужно будет его скопировать.

Следующая проблема в том, что c_str () не возвращает LPCWSTR, это LPCSTR.Бросок не может преобразовать это, которое производит китайский язык.Вам нужно будет преобразовать его в строку Unicode, например, с помощью MultiByteToWideChar ().

0 голосов
/ 06 февраля 2010

Конечно, есть способ преобразовать вашу строку во что-то. Вы можете взять адрес и передать его как LPCWSTR или как LPVOID (в случае LPVOID это может быть иначе).

Теперь внимательно прочитайте приведенное выше утверждение.

Чтобы знать, что делать, сначала вы должны знать, что такое LPCWSTR и LPVOID. У меня странное чувство, что это могут быть указатели. MSDN может помочь. Попробуйте здесь например

Тогда Вы должны знать, что функция, которой вы передаете эти параметры, будет делать с памятью, на которую указывают указатели. Это собирается просто прочитать это или возможно изменить это? И как это будет интерпретировать это в случае LPVOID.

Я не могу помочь вам с LPVOID, потому что я не знаю API, но LPCWSTR предлагает вам создать нулевую завершенную строку wide , которая будет просто читаться. Как насчет создания wstring и использования его метода c_str ()?

0 голосов
/ 06 февраля 2010

LPVOID просто void *, поэтому вы можете конвертировать любой указатель на него, так как любой указатель может быть преобразован в void *. Однако это не гарантирует, что эта операция даст действительный результат с точки зрения ваших ожиданий.

Проще говоря, LPVOID используется в ситуациях по следующей схеме

int i = 10; // some real data
int* pi = &i; // pointer to data

// convert to opaque pointer, not usable (readable), onlly can be passed around
// for instance to thread procedure
void* pv = pi;

pi = reinterpret_cast<int*>(pv); // convert back to pointer to data
int j = *pi; // access real data

Проблема в том, что вы должны гарантировать, что i будет оставаться в живых по крайней мере до тех пор, пока данные будут доступны / использованы через указатель pv. Вы должны рассмотреть, если ваш W

Итак, вы можете сделать это:

bool httpWrapper::setPostData(const string &postData){ 

 _postData = reinterpret_cast<LPVOID>(postData.c_str()); 
 return false; 
}

но вы должны гарантировать, что строковый объект, который вы передаете по ссылке как postData, останется в живых по крайней мере до тех пор, пока _postData указывает на него. Фактически, _postData указывает на внутреннее местоположение, возвращаемое c_str()

Также, похоже, вы собираетесь использовать значение, возвращаемое c_str(), как LPWSTR. Чтобы использовать LPWSTR, вам нужно, например, преобразовать ANSI в широкие символы, используя функцию MultiByteToWideChar .

Другими словами, преобразование из одного указателя в другой само по себе не является проблемой. Проблема состоит в том, чтобы гарантировать надлежащее время жизни и использования объектов.

0 голосов
/ 06 февраля 2010

Используйте это:

bool httpWrapper::setPostData(const string &postData){ 

 _postData = (LPWSTR)postData.c_str(); 

 _postData_len = 47; // Something else, actually.

 return false; 
}

LPWSTR _postData;

Вы можете передать LPWSTR методам, которые ожидают LPCWSTR. Так что вы можете работать со строками.

Кстати, вы только что попробовали передать строку сама? Я ожидаю, что это тоже сработает, и это лучше, чем выпуск LPWSTR.

Итак, в этом случае это будет выглядеть так:

bool httpWrapper::setPostData(const string &postData){ 

 _postData = postData; 

 _postData_len = 47; // Whatever.

 return false; 
}
string _postData;
...