i am currently learning C++ and want to change my desktop wallpaper. However i am getting this error above.
#include <string>
#include <iostream>
#include <Windows.h>
using namespace std;
int main() {
LPWSTR test = L"C:\\Users\\user\\Pictures\\minion.png";
int result = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0,
test, SPIF_UPDATEINIFILE);
}
A value of type "Const wchar_t*" cannot be used to initialize an entity of type LPWSTR
Any ideas?
Thanks
LPWSTR is an alias for wchar_t*, ie a pointer to a non-const character.
A string literal is a const array of characters, in your case a const wchar_t[35]. It decays into a pointer to a const character, pointing at the 1st character in the literal.
You can't assign a pointer-to-const to a pointer-to-non-const. That would allow writing access to read-only memory.
Use LPCWSTR instead, which is an alias for const wchar_t*.
LPCWSTR test = L"C:\\Users\\user\\Pictures\\minion.png";
The MSVC compiler is getting less and less permissive. On the whole that's a good thing.
L"C:\\Users\\user\\Pictures\\minion.png" is a literal of type const wchar_t[34] (the extra element is for the string terminator). That decays to a const wchar_t* pointer in certain circumstances.
LPWSTR is not a const pointer type so compilation will fail on a standard C++ compiler.
The solution is to use the const pointer type LPCWSTR.
Another way to resolve this compilation error is to set Conformance Mode to Default in the project Properties -> C/C++ -> Language. At least it worked in my VS2019 project.
Related
I'm trying to pass a process name as a TCHAR to the following void:
void GetBaseAddressByName(DWORD pID, TCHAR *pN)
By doing it like this:
GetBaseAddressByName(aProcs[i], (TCHAR*)"Process.exe");
So my question is: is what I am doing correct? Because I have tried both TEXT("Process.exe") and _T("Process.exe") with my project's Character Set both on Multi-Bite and Unicode and it just tells me that
argument of type "const char*" is incompatible with parameter of type "TCHAR*"
The short answer is no. TCHAR maps to either char or wchar_t depending on your project's Unicode/Multi-byte setting. So, in general, a cast like that is either unnecessary or incorrect. The correct way, as you said, is to use either the TEXT or _T macro. The reason you're getting an error is that you're trying to pass a const character string to a function that expects a mutable character string. The safeset way to get around the error is to copy your constant string into a local TCHAR buffer and then pass that to GetBaseAddressByName.
It is better to have a TCHAR array first, then copy into it.
#include "atlstr.h"
char const * procName = "processName.exe";
TCHAR szName [128];
_tcscpy(szName, A2T(procName));
GetBaseAddressByName(aProcs[i], szName);
As suggested by #Remy Lebeau in the comments, procName can be defined as TCHAR const * procName = TEXT("processName.exe");.
(TCHAR*)"Process.exe" is not a valid type-cast. It will "work" when the project charset is set to ANSI/MBCS, but it will produce garbage if the charset is set to Unicode.
Using TEXT("Process.exe") is the correct way to make a string literal use TCHAR characters.
GetBaseAddressByName(aProcs[i], TEXT("Process.exe"));
However, you need to change your pN parameter to const TCHAR * (or LPCTSTR) instead:
void GetBaseAddressByName(DWORD pID, const TCHAR *pN);
void GetBaseAddressByName(DWORD pID, LPCTSTR pN);
A string literal is const data, and you cannot pass a pointer-to-const-data where a pointer-to-non-const-data is expected (without casting the const away with const_cast). That is why you were still getting errors when trying to use the TEXT()/_T() macros.
You need a L, like L"Process.exe". Unicode strings are specified with L"".
That said, there is no reason to use TCHAR. Use unicode all the time, if doing Windows work only.
How to assign a variable to the value of const char *GetVersion()?
I am using a third-party library which states that const char *GetVersion() is available. The below code compiles successfully:
#include <iostream>
#include <Windows.h>
#include "ThirdPartyLibrary.h"
int main()
{
const char *GetVersion();
}
How to assign const char *GetVersion() to a variable?
Update
char const *GetVersion()
The version of the Application manual
interface that has loaded the running extension. This version is
distinct from the API version, which is documented in Macros , below.
Your code compiles since the compiler understands
const char *Function();
as being a function prototype.
First of all, read the documentation. It looks like you can simply write
const char* my_variable = Function();
But do check if you need to release any memory. (My hunch is that you don't given the return type is a const, but perhaps you need to call back into that library passing my_variable as the parameter).
How to assign const char *GetVersion() to a variable?
I'd suggest to immediately safely store the raw C-style string pointer returned by your C-interface function to a std::string object:
std::string version = GetVersion();
It's much better/safer/more convenient in C++ to manage strings using proper string classes than using C-style raw pointers.
You should also read your function documentation, to find out if you have to release the memory pointed by the returned const char*, or if this is not required.
Everything was working fine just five minutes ago when I tapped f5 and got 102 errors:
error: C2440: 'initializing' : cannot convert from 'const char [17]' to 'char *'
Conversion from string literal loses const qualifier (see /Zc:strictStrings)
That specific one is at line 30:
char* hexchars = "0123456789ABCDEF";
I haven't touched the file the errors are in for at least a week. I'd normally say I accidentally changed something in the compile args or something, but I haven't opened settings since much before it started erroring.
Any ideas? I must have absentmindedly changed some setting but I really can't remember thinking "uh oh what did I just do?"
When you use code like this
char *astring2 = "some letters";
C++ (and C) puts that into read only memory. You can not modify the contents of a char pointer initialized with a literal even if it is not const.
Also you can not change the address of the pointer because it will cause a memory leak due to the rule above.
This, however, does not follow that rule UNLESS you make it const:
char astring[] = "some letters that can be changed";
char *ptrToString = astring; //work
astring2 = astring //not work
String literals are of type char const[N] since C++ was first standardized. At this point C didn't support const and a lot of code assigned string literals to char*. As a result a special rule was present in C++ which allowed initialization of char* from string literals. This rule was immediately deprecated.
C99 introduced a const keyword, too. When C++11 was standardized the deprecated rules was pulled and it is no illegal to initialize a char* from a string literal as it should have been right from the stand. The expectation was that C++ compilers warned about the deprecated assignment since years (and all vendors stated they did), i.e., users had years of lead-time to fix their code.
The obvious fix is to initialize a char const* instead of a char* from a string literal.
If you really need a pointer to a mutable array of chars you can create it and get it initialized using
char array[] = "string literal";
I have an old C/C++ package which I am trying to compile with CygWin because it needs Motif and other X- things. Most of it compiles OK but there are some warnings due to lines like....
static String fallbackResources[] = { "Joe", ..etc.. , NULL};
I get the compiler warning: deprecated conversion from string constant to ‘String {aka char*}’
I have googled and found many suggestions to avoid this warning by changing occurrences of say "char* fred[]" to "const char* fred[]" which I have done for most of the c++ files in the package and this has worked perfectly to remove the compiler warnings.
However I am stuck with the "static String" lines since when I change them by inserting "const" before "String" it makes no difference and if I change the "String" to "const char*" the warning disappears but the program doesn't compile due to an error later on where it sends the array to another function....
cannot convert ‘const char*’ to ‘char**’ for argument ‘7’ to....
Any help would be very much appreciated.
Thanks all, googled more and found (https://stackoverflow.com/a/14648630/3100869) - the answer seems to be to use const_cast's like this:
static String fallbackResources[] = { const_cast("Joe"), ..etc.. , NULL};
... and the warnings go away!
The problem is that you've got two levels of const on pointers: the pointer itself and what it points to. char const * is a pointer to const char (read from right to left), whereas char* const is a const pointer to char.
It seems that String in your case is a typedef for char*. Making that const like you did turns it into a char* const. You need to fix the typedef.
I'm having trouble converting from LPSTR to const char* in MinGW under Windows.
#include <dirent.h>
#include <cstdio>
#include <fstream>
#include <windows.h>
int main() {
DIR *dir;
struct dirent *ent;
LPSTR buffer;
GetCurrentDirectory(100, buffer);
const char *str = *buffer;
dir = opendir(*str);
return 0;
}
What I'm trying to do is grab a list of all the current files in a directory and write it to a file; I can do the latter, but the former is giving me some trouble. I can figure out how to read the directory once I can convert the different variable types.
I know what LPSTR is, but I don't know how to apply it to this code.
Do not suggest using atlbase.h because MinGW does not support it, and I'm not willing to go back to Visual unless absolutely necessary.
You seem to be a bit confused about indirection. LPSTR is a char*. It is a pointer to a char (or, as is the case here, a pointer to the initial element of an array of char).
When you call GetCurrentDirectory, you need to pass it a pointer to the initial element of an array of char and the size of that array. So, what you need to do is declare an array and pass that into the function. For example,
char buffer[MAX_PATH];
GetCurrentDirectory(MAX_PATH, buffer);
With your current implementation, your program will assuredly crash because buffer is uninitialized, so GetCurrentDirectory will attempt to write to some random location in memory.
You should also check the return value of GetCurrentDirectory to ensure that it completed successfully and that the buffer contains the complete path. Its documentation explains the values that it may return.
Once you have the path, you can pass it directly to opendir: the array buffer is implicitly convertible to a pointer to its initial element--that is, the char[MAX_PATH] can be converted to a char*--and that char* can be implicitly converted to the char const* required by opendir:
DIR* dir = opendir(buffer);
Do note that the signature of GetCurrentDirectory depends on whether the UNICODE macro is defined or not: if you are compiling your program for Unicode, it actually takes a pointer to an array of wchar_t. If you build a Unicode program, you will need to account for this (you should use Unicode if you can).