Jump to content
  • Advertisement
Sign in to follow this  

Help converting char* to wchar_t*

This topic is 4133 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi. I need to convert a char* to a wchar_t*, so I'm using: int a = lstrlenA(charName); BSTR unicodeString = SysAllocStringLen(NULL, a); ::MultiByteToWideChar(CP_ACP, 0, charName, a, unicodeString, a); ::SysFreeString(unicodeString); , with charName being a char* declared earlier. Anyway, with the last two lines, I'm getting linker errors involving unresolved externals. I'm using #pragma comment (lib, "Kernel32.lib"), so I don't see why I'm having this problem. Any help would be appreciated.

Share this post


Link to post
Share on other sites
Advertisement
You can use std::basic_string to do this operation:

std::wstring Dummy(const std::string & rString)
{
return std::wstring(rString.begin(), rString.end());
}

Share this post


Link to post
Share on other sites
I'm getting "this program has performed an illegal blah blah blah tell M$ blah" errors when I use that function. It compiles alright, though.

Share this post


Link to post
Share on other sites
Quote:
Original post by Anteater
I'm getting "this program has performed an illegal blah blah blah tell M$ blah" errors when I use that function. It compiles alright, though.
How are you using it, exactly?

Share this post


Link to post
Share on other sites
A BSTR isn't a pure Unicode string. The first four bytes of a BSTR contain the length of the data string. A wchar_t string doesn't contain that information.

This might help: Guide to BSTR and C String Conversions

Meanwhile, here are a couple of functions wrapping WideCharToMultiByte and MultiByteToWideChar. YMMV.


// ----------------------------------------------------------------------------
//
//
BOOL WINAPI UnicodeToAnsi(
LPWSTR pszwUniString,
LPSTR pszAnsiBuff,
DWORD dwAnsiBuffSize
)
{
int iRet = 0;
iRet = WideCharToMultiByte(
CP_ACP,
0,
pszwUniString,
-1,
pszAnsiBuff,
dwAnsiBuffSize,
NULL,
NULL
);
return ( 0 != iRet );
}


// ----------------------------------------------------------------------------
//
//
BOOL WINAPI AnsiToUnicode(
LPSTR pszAnsiString,
LPWSTR pszwUniBuff,
DWORD dwUniBuffSize
)
{

int iRet = 0;
iRet = MultiByteToWideChar(
CP_ACP,
0,
pszAnsiString,
-1,
pszwUniBuff,
dwUniBuffSize
);

return ( 0 != iRet );
}




MultiByteToWideChar

cbMultiByte If this parameter is -1, the function processes the entire input string, including the null terminator. Therefore, the resulting wide character string has a null terminator, and the length returned by the function includes the terminating null character.

Share this post


Link to post
Share on other sites
What character encoding does your char* string have? If it's ASCII (all values are 0-127) or ISO-8859-1 (0-255, assuming char is unsigned) then using string s("example"); wstring w(s.begin(), s.end()); should do what you want. If it's anything else (UTF-8, or CP_ACP (whatever the user happens to have set Windows to)), then you'll probably need to use MultiByteToWideChar.

If you are using MultiByteToWideChar, you need to allocate enough space in the output, but your code looks a bit dangerous because SysAllocStringLen doesn't know how wide a character might become - a single char in the code page might map onto two wchar_t's, if its Unicode codepoint is above 64K or if it's represented by multiple codepoints, at least in theory. (Does anyone know if that actually happens in practice, particularly with the Unicode changes in Vista?)

It should work to do
int len = ::MultiByteToWideChar(CP_ACP, 0, charName, -1, NULL, 0);
LPWSTR unicodeString = new WCHAR[len];
::MultiByteToWideChar(CP_ACP, 0, charName, -1, unicodeString, len);
...
delete[] unicodeString
though I've not actually tested that and never written code like that before - I just stick with Unicode and ASCII and ignore code pages, because that makes life much easier [smile]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
You can use std::string to do this operation:


This does not work as expected for all characters. std::string is based on char, which could be signed or unsigned, make sure to use unsigned chars when converting to std::wstring.


std::wstring Dummy(const std::string & rString)
{
const unsigned char *str =
reinterpret_cast(rString.c_str());
return std::wstring(str, str + rString.size());
}

Share this post


Link to post
Share on other sites
There is also a function, mbstowcs() defined in the standard C library. It is similar to MultiByteToWideChar(). Here is a quick code snippet.
...
char* src = "Hello World.";
wchar_t dst[1024];
mbstowcs(dst, src, 1023);
...

Note that it just demonstrates how to use mbstowcs(), and it is not safe. You must check the return value; -1 for error and the number of characters should be less than wchar_t array size.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by raz0r
You can use std::basic_string to do this operation:

*** Source Snippet Removed ***


Sorry, but for a lot of multibyte character sets that will generate completely bollox results for strings that contain non-english characters.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!