c++ - A header file to directly write wide string literal
- hirofield (40/40) Sep 21 2009 Hi,
- Matthew Wilson (28/69) Nov 20 2009 Haven't compiled it, but I can tell you that it's got issues wrt excepti...
Hi, I wrote a header file to resolve wide string literal issue. Previously, when UNICODE is defined, wide string literals like L"foo" or _T("foo") doesn't work correctly (garbled). In this case, programmers must write wide string literals in character codes by using \u. e.g.) // Garbled ::MessgaeBoxW(NULL, _T("Hello"), _T("Title"), MB_OK); This header file resolve the problem (this requires STLPort). // dmctchar.h #ifndef DMCTCHAR_H #define DMCTCHAR_H #include <windows.h> #include <tchar.h> #include <string> using namespace std; namespace { // nameless namespace // MBCS->UNICODE converting function wstring MultiByteToWstr(const char* mbChar, UINT cp) { // Get buffer size int numChars = ::MultiByteToWideChar(cp, 0, mbChar, -1, NULL, 0); wchar_t* pWst = new wchar_t[numChars]; // Conversion numChars = ::MultiByteToWideChar(cp, 0, mbChar, -1, pWst, numChars); wstring result = wstring(pWst); delete[] pWst; return result; } } #ifdef UNICODE #undef _T #define _T(str) MultiByteToWstr(str, ::GetACP()).c_str() #endif // UNICODE #endif // DMCTCHAR_H When UNICODE is defined, Include above header file after tchar.h in your program, and you can write wide string literals directly as _T("foo"). Please feel free to use it if you faced with this problem. Your bug reports are appreciated. hirofield
Sep 21 2009
Your bug reports are appreciated.Haven't compiled it, but I can tell you that it's got issues wrt exception-safety and error-conditions. First, you don't check the return value of MultiByteToWideChar(). If it returns 0, you may want to just return wstring(). Second, if the expression wstring result = wstring(pWst); throws an exception, then the memory in the wide-char array will be leaked. (btw, you can just write wstring result(pWst); or, even better, wstring result(pWst, static_cast<size_t>(numChars)); ) Third, you might consider avoiding the (potentially unnecessary) explicit memory allocation, and use an auto_buffer instead; see www.ddj.com/cpp/184401740 and http://www.stlsoft.org/doc-1.9/classstlsoft_1_1auto__buffer.html wstring MultiByteToWstr(const char* mbChar, UINT cp) { // Get buffer size int numChars = ::MultiByteToWideChar(cp, 0, mbChar, -1, NULL, 0); stlsoft::auto_buffer<wchar_t> buff(numChars); // Conversion numChars = ::MultiByteToWideChar(cp, 0, mbChar, -1, &buff[0], numChars); wstring(&buff[0], numChars); return result; } // if any memory allocated in buff, will be freed here automatically btw, the second problem now disappears as well. Four, I'm not sure what you're doing with redefining _T(), but it looks suspicious. I'd need to hear more from you before commenting, but I think you're doing something that might screw up other code. HTH Matt "hirofield" <hi_ohta nifty.com> wrote in message news:h9810v$3bi$1 digitalmars.com...Hi, I wrote a header file to resolve wide string literal issue. Previously, when UNICODE is defined, wide string literals like L"foo" or _T("foo") doesn't work correctly (garbled). In this case, programmers must write wide string literals in character codes by using \u. e.g.) // Garbled ::MessgaeBoxW(NULL, _T("Hello"), _T("Title"), MB_OK); This header file resolve the problem (this requires STLPort). // dmctchar.h #ifndef DMCTCHAR_H #define DMCTCHAR_H #include <windows.h> #include <tchar.h> #include <string> using namespace std; namespace { // nameless namespace // MBCS->UNICODE converting function wstring MultiByteToWstr(const char* mbChar, UINT cp) { // Get buffer size int numChars = ::MultiByteToWideChar(cp, 0, mbChar, -1, NULL, 0); wchar_t* pWst = new wchar_t[numChars]; // Conversion numChars = ::MultiByteToWideChar(cp, 0, mbChar, -1, pWst, numChars); wstring result = wstring(pWst); delete[] pWst; return result; } } #ifdef UNICODE #undef _T #define _T(str) MultiByteToWstr(str, ::GetACP()).c_str() #endif // UNICODE #endif // DMCTCHAR_H When UNICODE is defined, Include above header file after tchar.h in your program, and you can write wide string literals directly as _T("foo"). Please feel free to use it if you faced with this problem. Your bug reports are appreciated. hirofield
Nov 20 2009