cxong / tinydir

Lightweight, portable and easy to integrate C directory and file reader

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Fails on UNICODE builds on Windows

seanmiddleditch opened this issue · comments

Compiling with the UNICODE macro (which is required by most other well-behaving Windows libraries) currently fails.

If you want to be ASCII-only then you must explicitly call the *A versions of functions, e.g. FindFirstFileA instead of FindFirstFile. The unadorned versions are macros that expand to either FindFirstFileW or FindFirstFileA depending on whether _UNICODE is in use or not.

A better bet would be to just be compatible with _UNICODE as there are some places where you need Windows' native UTF16 paths and can't use the ASCII variants. To do this you need to use TCHAR instead of char for your strings and buffers and use the the TEXT macro to wrap all your literals.

Yeah, Windows is lame for not just being UTF8 everywhere, but it is what it is. Recommended practice for Win32 developers is to use UTF8 internally for all strings, enable _UNICODE to catch mistakes like this one with Win32 calls, to always explicitly call the *W variants of functions (in case a user turns off _UNICODE), and then do any translation to and from UTF16/UTF8 at the boundaries where Win32 OS calls are made.

For a library like this one, I think the best option would be to just support both modes using the macros described above.

Errors received with latest tinydir when using _UNICODE:

1>C:\Users\Sean\Documents\Projects\tinydir/tinydir.h(142): error C2664: 'HANDLE FindFirstFileW(LPCWSTR,LPWIN32_FIND_DATAW)' : cannot convert argument 1 from 'char [4096]' to 'LPCWSTR'
1>          Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>C:\Users\Sean\Documents\Projects\tinydir/tinydir.h(327): error C2664: 'size_t strlen(const char *)' : cannot convert argument 1 from 'const WCHAR [260]' to 'const char *'
1>          Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>C:\Users\Sean\Documents\Projects\tinydir/tinydir.h(340): error C2664: 'size_t strlen(const char *)' : cannot convert argument 1 from 'const WCHAR [260]' to 'const char *'
1>          Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>C:\Users\Sean\Documents\Projects\tinydir/tinydir.h(354): error C2664: 'char *strcpy(char *,const char *)' : cannot convert argument 2 from 'const WCHAR [260]' to 'const char *'
1>          Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
commented

Not being familiar with wide char issues, I think I'll go with using the *A versions for now, as that will make the errors go away. It would be nice to support wide char paths across all platforms eventually.

seanmiddleditch@f0254be fixes both this and #18 with merge conflicts already resolved.

For unicode support, may I suggest using *W versions of the api, then using WideCharToMultiByte with CP_UTF8 to convert to UTF-8?

That way the api is UTF-8 on both windows and linux.