wchar_t...how do I use it?

Started by
5 comments, last by Aardvajk 17 years, 8 months ago
I've been working on a project for a while with an API I am learning and I've stumbled across a function that uses a datatype called 'wchar_t' which is highlighted like any other primitive type in VC++. On Wikipedia it said that this is a 'wide' character which is not compiler independant. Now I am currently wondering how I can use this char without having literal strings in my program. basically my problem is that currently my code would have to look like this: MyFunction(param1, param2, "my literal String, bad"); But I want to be able to have dynamic strings (ie strings read from a script, etc) MyFunction(param1, param2, myClassThatCanHoldand/orBeConvertedToAwchar_t); If your wondering, the function im dealing with is part of Direct3D's X library: D3DXLoadMeshFromX(..); its the first parameter for the file name. its disguised as a typedef LPCTSTR
Advertisement
If you use wide character strings throughout your program, you can use std::wstring as your string time. std::wstring::c_str() will return a wchar_t*, precisely what that function wants. To specify a string literal that uses wide characters, put a capital 'L' in front of the string:

std::wstring Sample = L"Wide";

Also, in your project settings, you'll probably want to have _UNICODE defined in your list of preprocessor defines. It might already be defined. This tells various APIs (usually Microsoft APIs) to use wide character versions of functions, rather than multi-byte character versions. There are basically a ton of functions that have two versions, and there is an #ifdef _UNICODE statement that #defines the specific function (wide character functions generally end with a 'W', and multi-byte character functions end with an 'A') to the general function (without the letter on the end).

In fact, this _UNICODE define is probably already there. If you replaced it with _MBCS (multi-byte character string), then DirectX will try to use the normal type of string for its functions, rather than the wide character version.

(I just checked d3dx9mesh.h, and sure enough, there is a D3DXLoadMeshFromXA() and D3DXLoadMeshFromXW(), and an #ifdef, though it is an #ifdef on UNICODE (no underscore). I don't know if UNICODE gets defined by some DirectX or Windows header if _UNICODE is defined. Either way, you can also ensure that UNICODE isn't in your list of preprocessor defines.)

From d3dx9mesh.h:
HRESULT WINAPI    D3DXLoadMeshFromXA(        LPCSTR pFilename,         DWORD Options,         LPDIRECT3DDEVICE9 pD3D,         LPD3DXBUFFER *ppAdjacency,        LPD3DXBUFFER *ppMaterials,         LPD3DXBUFFER *ppEffectInstances,         DWORD *pNumMaterials,        LPD3DXMESH *ppMesh);HRESULT WINAPI    D3DXLoadMeshFromXW(        LPCWSTR pFilename,         DWORD Options,         LPDIRECT3DDEVICE9 pD3D,         LPD3DXBUFFER *ppAdjacency,        LPD3DXBUFFER *ppMaterials,         LPD3DXBUFFER *ppEffectInstances,         DWORD *pNumMaterials,        LPD3DXMESH *ppMesh);#ifdef UNICODE#define D3DXLoadMeshFromX D3DXLoadMeshFromXW#else#define D3DXLoadMeshFromX D3DXLoadMeshFromXA#endif
"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke
I'd recommend using std::wstring instead, the wide-character implementation of the std::string.

Directx SDK uses "T" macros for strings. Like LPCTSTR. This depending on the project setting Multi-byte or Unicode, will transform into LPCSTR or LPCWSTR respectively. It really depends on what you want in your project and how you load the dinamyc strings.

A wide character literal is defined like this L"Some text here", with that extra L added. Same as before the macro TEXT("") and T("") will change into "" or L"" depending on character settings setting.

Hope this helps.
Every time you implement a singleton, God kills a kitten. Please, think of the kittens!
Ah, Thankyou very much ( I really should look at std:: some more ). Is it common to find two definitions of a function just for two string types?
Quote:Original post by luke2
Ah, Thankyou very much ( I really should look at std:: some more ). Is it common to find two definitions of a function just for two string types?


Yes. The Win32 API uses them all over the place.

We have an #ifdef to typedef std::string or std::wstring to AString depending on whether or not _UNICODE is defined.
[ search: google ][ programming: msdn | boost | opengl ][ languages: nihongo ]
Quote:Original post by luke2
Is it common to find two definitions of a function just for two string types?


Yes. Few years ago, WinAPI didn't support Unicode natively and when it was added they had to retain compatibily with older applications, so they made two versions of each function. One version uses Unicode string, other uses multi-byte.
Now, all WindowsNT (IIRC) based systems (e.g. WinXP, Vista, 2k3...) are all using Unicode by default (core API is in Unicode). So if you use non-unicode API, all strings are first converted to the Unicode and then Unicode API function is called. Therefore, I recommend using Unicode (especially if you are calling a lot of API function with string parameters). I believe that this is the reason why UNICODE is being defined by default when creating new C++ project in VS2k5.
Don't know if this helps, but Windows provides <tchar.h> for the TCHAR macro which will resolve to either char, wchar_t or whatever is being used by the project. You can then do:

std::basic_string<TCHAR> s;

for example to create a string object that uses whatever the project settings tell it to.

This topic is closed to new replies.

Advertisement