Respostas:
str.c_str()fornece um const char *, que é um LPCSTR(Ponteiro longo para STRing constante) - significa que é um ponteiro para uma 0string terminada de caracteres. Wsignifica string larga (composta de em wchar_tvez de char).
Ligue c_str()para obter um const char *( LPCSTR) de a std::string.
Está tudo no nome:
LPSTR - ponteiro (longo) para string - char *
LPCSTR - ponteiro (longo) para string constante - const char *
LPWSTR - ponteiro (longo) para string Unicode (larga) - wchar_t *
LPCWSTR - ponteiro (longo) para string Unicode (ampla) constante - const wchar_t *
LPTSTR - ponteiro (longo) para TCHAR (Unicode se UNICODE for definido, ANSI se não) string - TCHAR *
LPCTSTR - ponteiro (longo) para string TCHAR constante - const TCHAR *
Você pode ignorar a parte L (longa) dos nomes - é um resquício do Windows de 16 bits.
Estes são typedefs definidos pela Microsoft que correspondem a:
LPCSTR: ponteiro para string const terminada em nulo de char
LPSTR: ponteiro para string de caracteres terminada em nulo de char (geralmente um buffer é passado e usado como um parâmetro de 'saída')
LPCWSTR: ponteiro para string terminada em nulo de const wchar_t
LPWSTR: ponteiro para string terminada em nulo de wchar_t(geralmente um buffer é passado e usado como um parâmetro de 'saída')
Para "converter" a std::stringem um LPCSTR depende do contexto exato, mas normalmente a chamada .c_str()é suficiente.
Isso funciona.
void TakesString(LPCSTR param);
void f(const std::string& param)
{
TakesString(param.c_str());
}
Observe que você não deve tentar fazer algo assim.
LPCSTR GetString()
{
std::string tmp("temporary");
return tmp.c_str();
}
O buffer retornado por .c_str()pertence à std::stringinstância e só será válido até a próxima modificação ou destruição da string.
Converter a std::stringem a LPWSTRé mais complicado. Querer um LPWSTRimplica que você precisa de um buffer modificável e também precisa ter certeza de que entende qual codificação de caracteres o std::stringestá usando. Se o std::stringcontém uma string usando a codificação padrão do sistema (assumindo janelas, aqui), então você pode encontrar o comprimento do amplo buffer de caracteres necessário e realizar a transcodificação usandoMultiByteToWideChar (uma função API do Win32).
por exemplo
void f(const std:string& instr)
{
// Assumes std::string is encoded in the current Windows ANSI codepage
int bufferlen = ::MultiByteToWideChar(CP_ACP, 0, instr.c_str(), instr.size(), NULL, 0);
if (bufferlen == 0)
{
// Something went wrong. Perhaps, check GetLastError() and log.
return;
}
// Allocate new LPWSTR - must deallocate it later
LPWSTR widestr = new WCHAR[bufferlen + 1];
::MultiByteToWideChar(CP_ACP, 0, instr.c_str(), instr.size(), widestr, bufferlen);
// Ensure wide string is null terminated
widestr[bufferlen] = 0;
// Do something with widestr
delete[] widestr;
}
Usando LPWSTRvocê pode alterar o conteúdo da string para onde ela aponta. Usando LPCWSTRvocê não pode alterar o conteúdo da string para onde ela aponta.
std::string s = SOME_STRING;
// get temporary LPSTR (not really safe)
LPSTR pst = &s[0];
// get temporary LPCSTR (pretty safe)
LPCSTR pcstr = s.c_str();
// convert to std::wstring
std::wstring ws;
ws.assign( s.begin(), s.end() );
// get temporary LPWSTR (not really safe)
LPWSTR pwst = &ws[0];
// get temporary LPCWSTR (pretty safe)
LPCWSTR pcwstr = ws.c_str();
LPWSTRé apenas um ponteiro para a string original. Você não deve retorná-lo da função usando o exemplo acima. Para não ser temporário, LPWSTRvocê deve fazer uma cópia da string original na pilha. Confira o exemplo abaixo:
LPWSTR ConvertToLPWSTR( const std::string& s )
{
LPWSTR ws = new wchar_t[s.size()+1]; // +1 for zero at the end
copy( s.begin(), s.end(), ws );
ws[s.size()] = 0; // zero at the end
return ws;
}
void f()
{
std::string s = SOME_STRING;
LPWSTR ws = ConvertToLPWSTR( s );
// some actions
delete[] ws; // caller responsible for deletion
}
A MultiByteToWideCharresposta que Charles Bailey deu é a correta. Como LPCWSTRé apenas um typedef para const WCHAR*, widestrno código de exemplo ele pode ser usado sempre que um LPWSTRfor esperado ou onde um LPCWSTRfor esperado.
Um pequeno ajuste seria usar em std::vector<WCHAR>vez de uma matriz gerenciada manualmente:
// using vector, buffer is deallocated when function ends
std::vector<WCHAR> widestr(bufferlen + 1);
::MultiByteToWideChar(CP_ACP, 0, instr.c_str(), instr.size(), &widestr[0], bufferlen);
// Ensure wide string is null terminated
widestr[bufferlen] = 0;
// no need to delete; handled by vector
Além disso, se você precisar trabalhar com strings largas para começar, poderá usar em std::wstringvez de std::string. Se você quiser trabalhar com o TCHARtipo do Windows , você pode usar std::basic_string<TCHAR>. A conversão de std::wstringpara LPCWSTRou de std::basic_string<TCHAR>para LPCTSTRé apenas uma questão de ligar c_str. É quando você muda entre ANSI e UTF-16 caracteres queMultiByteToWideChar (e seu inverso WideCharToMultiByte) entra em cena.
A conversão é simples:
std::string myString;
LPCSTR lpMyString = myString.c_str();
Uma coisa a ter cuidado aqui é que c_str não retorna uma cópia de myString, mas apenas um ponteiro para a string de caracteres que std :: string envolve. Se você quiser / precisar de uma cópia, você mesmo precisará fazer uma usando o strcpy.
A maneira mais fácil de converter a std::stringem a LPWSTRé, em minha opinião:
std::stringem umstd::vector<wchar_t>wchar_tno vetor.std::vector<wchar_t>tem um ctor modelado que terá dois iteradores, como os iteradores std::string.begin()e .end(). No wchar_tentanto, isso converterá cada char em um . Isso só é válido se std::stringcontiver ASCII ou Latin-1, devido à forma como os valores Unicode se assemelham aos valores Latin-1. Se contiver CP1252 ou caracteres de qualquer outra codificação, é mais complicado. Em seguida, você precisará converter os personagens.
std::wstring?