I have a program I am modifying to take command line argument as a variable of the type LPSTR
. Currently the value is hardcoded in the program and passes to the desired function in the form _T("program.exe")
. The function expects the type LPCTSTR
. I have tried to cast my command line argument from a LPSTR
to a LPCTSTR
to no avail. Similar attempts using a char*
as an intermediary have also failed. I know I am probably missing something stupidly simple, but at this point I would appreciate the help.

- 24,473
- 8
- 65
- 91

- 162
- 2
- 13
-
Why is your input LPSTR and not LPTSTR? The `GetCommandLine` function for getting command line arguments and the arguments to the `_tWinMain` function should give you LPTSTR in a Unicode build. – interjay Jun 08 '17 at 15:53
-
1Not a duplicate, but this question might be of interest to you OP: https://stackoverflow.com/questions/234365/is-tchar-still-relevant – Govind Parmar Jun 08 '17 at 15:55
-
1Why oh why are you using `TCHAR`? Do you need to compile both for ANSI and Unicode? Are you still targeting Windows 98? I doubt it. Compile for Unicode, use `wchar_t`, and make up your mind whether you write C or C++. – David Heffernan Jun 08 '17 at 15:56
-
@interjay the argument is being grabbed in the dllEntryPoint function – Falderol Jun 08 '17 at 15:58
-
@David Heffernan I am trying to modularise an old piece of code and if at all possible would like to change as little as possible. – Falderol Jun 08 '17 at 15:59
-
1I think you'll need to start off by learning about `TCHAR` then. As it stands, I don't think you even know what `TCHAR` expands to? Is it `char` or `wchar_t`? You need to know that, and understand the implications. That's your next task of research. – David Heffernan Jun 08 '17 at 16:02
-
@DavidHeffernan Actually its not Unicode, its UTF-16LE – Passer By Jun 08 '17 at 16:08
-
@PasserBy In Windows API world, when we say Unicode we mean UTF-16LE. The conditional define is `UNICODE` and not `UTF16LE`. Yes, Win32 is sloppy here, but of course when it started out we didn't have all the Unicode encodings that we currently have. – David Heffernan Jun 08 '17 at 16:11
-
1@DavidHeffernan Yeah, I know. I'm just terrified OP would hereon out think that Unicode is an encoding – Passer By Jun 08 '17 at 16:16
-
@interjay: The type of the return value of [GetCommandLine](https://msdn.microsoft.com/en-us/library/windows/desktop/ms683156.aspx) is **always** `LPTSTR`, irrespective of project settings. – IInspectable Jun 08 '17 at 16:55
-
@IInspectable Yes, I meant to say that it is a wide string in a Unicode build. – interjay Jun 08 '17 at 17:33
-
I know this is four years late, but to clarify, this was a piece of legacy code that did things in a kludgy, and apparently incorrect way that made people so upset they downvoted it into oblivion. Yes, someone, somewhere converted a command line argument up several levels into a LPSTR and then only passed it to us as that. At the time I was only allowed to change the one file, which meant the downvoted answer, not the get command line arguments differently or just convert everything to not unicode, worked for me. – Falderol Jan 06 '22 at 03:24
3 Answers
If your project is using Unicode by default, _T("String")
will become L"String"
, which is a wide-character string. You cannot convert between wide-character strings and 8-bit character strings using a type-cast.
Your options:
- Change your project settings to not use the Unicode character set.
- Use the Unicode functions instead of the ANSI ones. Define your application entry point to be
wWinMain
instead ofWinMain
, and the command-line parameter to beLPWSTR lpCmdLine
.

- 20,656
- 7
- 53
- 85
-
1Not the downvoter, but your first option is the opposite of what OP wants: `_T("")` works already, and `""` wouldn't, but she wishes to pass in a dynamic value instead of a hard-coded one. – Quentin Jun 08 '17 at 15:53
-
@Quentin Point taken - I just re-read the OP's question carefully. – Govind Parmar Jun 08 '17 at 15:54
-
1The second suggestion, however, is better. If you don't use Unicode, your application will be stuck in the 20th century. – Harry Johnston Jun 08 '17 at 22:15
Since you are dealing with a command-line parameter, you are presumably using argv
.
You should instead be using the CommandLineToArgvW
function, which produces an argv-like array of Unicode strings. There is example code at the bottom of the linked documentation, but it goes basically like this:
argv_wide = CommandLineToArgvW(GetCommandLineW(), &argc_wide);
Note that if you had obtained the ANSI string in some other way, e.g., read from a text file, you would instead use the MultiByteToWideChar
function to convert it.

- 35,639
- 6
- 68
- 158
-
I honestly would love to use argv, it is much nicer. But I was trying to keep the legacy code as close to the original, but get it running on this is. – Falderol Jun 09 '17 at 12:55
-
From your description, the part of the code that takes the argument from the command line rather than hard-coding it is new, so that's the part you can change, yes? If you aren't using `argv` to read from the command line, what are you using? – Harry Johnston Jun 09 '17 at 22:43
Normally LPSTR should convert to LPCTSTR.
However, it’s obviously not in your case, so stating that doesn’t help anyone.
If you’re using Visual Studio, got to Project ⟩ [Project Name] Properties ⟩ Configuration Properties ⟩ General ⟩ Project Defaults and change the value of Character Set to ‘Use Multi-Byte Character Set’
If you’re using a custom .vcxproj
file, inside of each
<PropertyGroup Condition= "'$(Configuration)|$(Platform)'=='[Configuration]|[Platform]'" Label="Configuration"></PropertyGroup>
you will need to add a line that says:
<CharacterSet>MultiByte</CharacterSet>
If you already have a <CharacterSet>
in there, then simply change its value to 'MultiByte'.

- 35,639
- 6
- 68
- 158

- 302
- 1
- 3
- 15
-
This will work, but should be a last resort, if you are dealing with legacy code that simply *can't* be updated to work with Unicode. From the sounds of it, the bulk of the code already supports Unicode, so it is just a matter of obtaining the command line argument correctly. – Harry Johnston Jun 08 '17 at 22:17
-
No-one claimed, that `LPSTR` wouldn't convert to `LPCSTR`. Stating that someone did, doesn't help anyone. Plus, your double and single quotes aren't. – IInspectable Jun 08 '17 at 22:59
-
I never said that anyone claimed LPSTR wouldn’t convert to LPCTSTR. Trying to parody my statement without using facts and ending your final sentence halfway through doesn’t help anyone. – Tom Metzger Jun 09 '17 at 13:00
-
He meant "your double and single quotes aren't double and single quotes". Your browser or operating system has converted them to so-called smart quotes, which means that if a reader copy-and-pasted them they'd get into trouble. I've fixed them. – Harry Johnston Jun 09 '17 at 22:40
-
Ah, I didn't catch that - thank you very much for the clarification and for the fix! – Tom Metzger Jun 09 '17 at 23:21