Sign in to follow this  
luke2

wchar_t...how do I use it?

Recommended Posts

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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this