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 ?
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
UNICODEdefine.This type of code looks like this:
There is no function named
GetDriveType, 99% of all functions that take a string parameter in Windows have two versions, in this caseGetDriveTypeAandGetDriveTypeW.Inside the Windows header files you have code that looks like this:
If UNICODE is defined before including windows.h the above code expands to:
and if not:
These days most applications should use Unicode. Whether you should use
wchar_t/WCHARand callGetDriveTypeWdirectly 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
_TEXTmacro and the _tcs functions except that those are controlled by the_UNICODEdefine.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 fromchar*to a wide string in some places.See also: