-8

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.

Stargateur
  • 24,473
  • 8
  • 65
  • 91
Falderol
  • 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
  • 1
    Not 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
  • 1
    Why 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
  • 1
    I 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 Answers3

4

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:

  1. Change your project settings to not use the Unicode character set.
  2. Use the Unicode functions instead of the ANSI ones. Define your application entry point to be wWinMain instead of WinMain, and the command-line parameter to be LPWSTR lpCmdLine.
Govind Parmar
  • 20,656
  • 7
  • 53
  • 85
  • 1
    Not 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
  • 1
    The 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
4

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.

Harry Johnston
  • 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
-3

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'.

Harry Johnston
  • 35,639
  • 6
  • 68
  • 158
Tom Metzger
  • 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