3
votes

I'll start by saying I know basically nothing about wide strings and Unicode support. I let QString and QFile handle that for me 99% of the time, but I'm trying to compile someone else's library written for VC6.

When I compile with MSVC2010 in Qt Creator I get this error:

error: C2664: 'FindFirstFileW' : cannot convert parameter 1 from 'const char *' to 'LPCWSTR'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

The code is using the FindFirstFile function, which is overloaded (sort of) depending on whether you're compiling with the Unicode character set. I don't understand what type FindFirstFile is expecting, when the input for FindFirstFileA and FindFirstFileW seems to be two completely different types.

So here's my question: What is the expected input type for FindFirstFile?

Corollary: How do I take a filename of type const char* and put it into a form that FindFirstType will accept?

2
That's not overloading. That's a macro to select one of two differently named functions. C has no overloading.chris
Okay, I'll change the phrasing to reflect that. FYI, my input to the function is a character array, not a string literal, so tacking on L doesn't help.Phlucious
If you need the code to work when compiled with or without the UNICODE preprocessor symbol (you probably don't), replace the call with FindFirstFile(_T("arg_0"), ...). Otherwise, replace the call with FindFirstFileW(L"arg_0", ...). To answer your question, the expected argument type is const char * if you're calling FindFirstFileA and const wchar_t * if you're calling FindFirstFileW.Praetorian
Hint: Don't get caught up in TCHARs. Use wide strings from the beginning and it's a lot less to worry about and will work in any version of Windows that's not really really old.chris
@chris or use UTF-8 everywhere and only convert when necessary: utf8everywhere.org although yours is the most practical advice.Mark Ransom

2 Answers

8
votes

FindFirstFile is a macro defined as follows:

#ifdef UNICODE
#define FindFirstFile  FindFirstFileW
#else
#define FindFirstFile  FindFirstFileA
#endif // !UNICODE

What this means is that it expands to the one with a W when compiled with UNICODE defined, and it expands to the one with an A otherwise.

Now, FindFirstFile's first parameter is either LPCSTR or LPWCSTR. LPCSTR is a typedef for const char* while LPWCSTR is a typedef for const wchar_t*. In your error message, you try passing a type of const char* as the first argument to FindFirstFileW which takes an argument of type const wchar_t*, hence the error.

In order for the types to match up, you need to pass an object of type const wchar_t*, you have several options:

std::wstring path1 = L"..."; // 1
const wchar_t* path2 = L"..."; // 2
wchar_t path3[] = L"..."; // 3

WIN32_FIND_DATA  w32fd;
FindFirstFile(path1.c_str(), &w32fd); // 1
FindFirstFile(path2, &w32fd); // 2
FindFirstFile(path3, &w32fd); // 3
FindFirstFile(L"...", &w32fd);

How do I take a filename of type const char* and put it into a form that FindFirstType will accept?

If your filename only contains characters in the basic ASCII character set, then you can convert it to a std::wstring like the following: std::wstring path(std::begin(filename), std::end(filename));. Otherwise, you would need to use MultiByteToWideChar or many of the options shown here. Another option would be to call FindFirstFileA directly, but if you are on windows, it generally would be better to use wchar_t to begin with.

0
votes

The expected input type is const wchar_t* if you are compiling for unicode. (Which you are: the 'W' tells us that.). The expected input type is const char* if you are not compiling for unicode. Before solving your problem you have to decide whether to compile for unicode or not. If you opt for unicode then your strings should be wchar_t* or std::wstring or CString. That should make your problem go away.

If you actually need to use a const char* in a unicode-compiled app then you have to convert the const char* into a const wchar_t* string by calling the MultiByteToWideChar API function.