Reputation: 1003
I have a C app that I need to compile in Windows
. And I am really unable to wrap my head around the UNICODE
and ANSI
concept in Windows
I want to use GetDriveType
function and there are 2 variables A
and W
. There is also a note here saying that GetDriveType
is an alias to both and will select either based on some pre-processor.
But how should I call this function ?
This is what I am trying:
const TCHAR* path = "C:\\Users\\";
const TCHAR* trailing_slash = "\\";
size_t requiredSize = mbstowcs(NULL, path, 0);
TCHAR* win_path = (char*)malloc((requiredSize + 2) * sizeof(char));
UINT driveType = 0;
strncpy(win_path, path, requiredSize + 1);
strncat(win_path, trailing_slash, 2);
printf("Checking path: %s\n", win_path);
driveType = GetDriveType(win_path);
wprintf(L"Drive type is: %d\n", driveType);
if (driveType == DRIVE_FIXED)
printf("Success\n");
else
printf("Failure\n");
return 0;
It produces the result
Checking path: C:\Users\
Drive type is: 1
Failure
If I replace GetDriveType
with GetDriveTypeA
it returns the correct value 3
and succeeds.
I tried another variant too
size_t requiredSize = mbstowcs(NULL, path, 0);
uint32_t drive_type = 0;
const wchar_t *trailing_slash = L"\\";
wchar_t *win_path = (wchar_t*) malloc((requiredSize + 2) * sizeof(wchar_t));
/* Convert char* to wchar* */
size_t converted = mbstowcs(win_path, path, requiredSize+1);
/* Add a trailing backslash */
wcscat(win_path, trailing_slash);
/* Finally, check the path */
drive_type = GetDriveType(win_path);
I see this warning:
'function' : incompatible types - from 'wchar_t *' to 'LPCSTR'
So, which one to use ? How is it generic ? The path I will be reading is from an environment variable on Windows
What is TCHAR
and wchar_t
etc. ? I found this post, but could not understand much
This Microsoft post says
Depending on your preference, you can call the Unicode functions explicitly, such as SetWindowTextW, or use the macros
So is it Ok to use wchar_t
everywhere and call GetDriveTypeW
directly ?
Upvotes: 0
Views: 519
Reputation: 101666
Back in the mid-90s you had Windows 95/98/ME that did not support Unicode and NT4/2000/XP that did. You could create source code that could compile with or without Unicode support just by changing the UNICODE
define.
This type of code looks like this:
UINT type = GetDriveType(TEXT("c:\\"));
There is no function named GetDriveType
, 99% of all functions that take a string parameter in Windows have two versions, in this case GetDriveTypeA
and GetDriveTypeW
.
Inside the Windows header files you have code that looks like this:
#ifdef UNICODE
#define GetDriveType GetDriveTypeW
#else
#define GetDriveType GetDriveTypeA
#endif
If UNICODE is defined before including windows.h the above code expands to:
UINT type = GetDriveTypeW(L"c:\\");
and if not:
UINT type = GetDriveTypeA("c:\\");
These days most applications should use Unicode. Whether you should use wchar_t
/WCHAR
and call GetDriveTypeW
directly or still rely on the defines is a style question. There might be situations where you need to force the A or W function and that is OK as well.
The same applies to the C library with the _TEXT
macro and the _tcs functions except that those are controlled by the _UNICODE
define.
If you get a warning about incompatible string types then you are calling the wrong function or you have not added #define UNICODE
(and _UNICODE
). If you are compiling cross platform code intended for Unix you might have to convert from char*
to a wide string in some places.
See also:
Upvotes: 2