2

The following code

string exePath() {
string path;
char buffer[MAX_PATH];
cout << "reading path\n";
GetModuleFileName(NULL, buffer, MAX_PATH);
string::size_type pos = string(buffer).find_last_of("\\/");
path = string(buffer).substr(0, pos)/*+"\\system.exe"*/;
return path;

}

gives me error at the second parameter in VisualStudio (buffer):

the type "char *" argument is incompatible with the type parameter "LPWSTR"

(translated from italian,i have vs in italian, hope you understand) and can't convert Char to LPWSTR in the 2 argument

This code compiles fine with code::blocks and dev c++ but in vs it doesn't

SergeyA
  • 61,605
  • 5
  • 78
  • 137
Mario Valentino
  • 65
  • 2
  • 10
  • 2
    Error message matches the title of [Argument of type "char \*" is incompatible with parameter of type "LPWSTR"](http://stackoverflow.com/questions/20611865/argument-of-type-char-is-incompatible-with-parameter-of-type-lpwstr), which suggests you didn't do much esarching before asking the question. – Raymond Chen Mar 31 '16 at 19:22

2 Answers2

3

Because GetModuleFileName is a macro definition for GetModuleFileNameW if UNICODE is defined and which requires wchar_t*. If no UNICODE is defined then GetModuleFileName resolves to GetModuleFileNameA. The simple fix for you is to use explicitly GetModuleFileNameA which accepts char*

This code compiles fine with code::blocks and dev c++ but in vs it doesn't

most probably because with code::blocks you compile with no UNICODE defined, while under VS by default UNICODE is defined.

If you are not using UNICODE, and want to stay with multibyte string (same as in code::blocks) you can disable UNICODE in your Visual Studio build by changing in project properties on General tab -> Character set to Use Multi-Byte Character Set.

[edit]

To avoid problems with UNICODE characters in the path it is recomended to use UNICODE. This requires you to use std::wstring which is specialization for wchar_t, also instead of char buffer[MAX_PATH]; you should use wchar_t buffer[MAX_PATH];. cout << "reading path\n"; would have to be wcout << L"reading path\n";. You can also use macros like TCHAR or _T("reading path"), to make it independently work for UNICODE and non-UNICODE builds.

marcinj
  • 48,511
  • 9
  • 79
  • 100
  • ok,now it works, thanks – Mario Valentino Mar 31 '16 at 18:59
  • While this is a solution, it removes the Unicode support, leaving you with the ASCII character set for all APIs, which breaks international applications on systems not set on the same locale. – coladict Mar 31 '16 at 19:18
  • @MarioValentino if your application is intended to show Unicode string with the use of Windows GUI frameworks (MFC o WinAPI) then - you might consider staying with UNICODE build. – marcinj Mar 31 '16 at 19:26
  • @marcinj have you got an example of non-ASCII file path? – Mario Valentino Mar 31 '16 at 19:48
  • because a path is C:\Hello\from\ITALY\ and i think that this is ASCII – Mario Valentino Mar 31 '16 at 19:49
  • You would have to use some accented characters, in my language polish - I can use c:\ąśćń\ół.txt. I suppose without unicode your code would break if path contains unicode characters which does not exists in current code page ( the one returned from GetACP() function). – marcinj Mar 31 '16 at 19:57
0

I believe this is related How I can print the wchar_t values to console?. You must also prefix your strings with L to make them wide-char like this

std::wcout << L"reading path" << std::endl;

This will work well if your application is for Windows only, but you should use the TEXT("reading path") macro style otherwise, because even though it's not there by default for other platforms, you can add it easily.

Community
  • 1
  • 1
coladict
  • 4,799
  • 1
  • 16
  • 27