-1

I recently switched from Visual studio code to Visual studio 2019 because I wanted to download C++ package using VCPKG.

My code worked on Visual Studio Code but do not work on Visual Studio 2019, maybe because it's not the same compilator.

The code I found on a StackOverflow post (Get Computer Name and logged user name) retrieve the Computer name and the Username of a PC.

#define INFO_BUFFER_SIZE 32767
TCHAR  infoBuf[INFO_BUFFER_SIZE];
DWORD  bufCharCount = INFO_BUFFER_SIZE;
SID_IDENTIFIER_AUTHORITY pIdentStruct = SECURITY_NT_AUTHORITY;
PSID ptrSidStruct;
BOOL isMember;

Constructor::Contructor(): c_online(true), c_status("Alive"), c_master("Master IP"), c_port(80) 
{

  bufCharCount = INFO_BUFFER_SIZE;
  if (GetComputerName(infoBuf, &bufCharCount))
  { 
    c_pc = TEXT(infoBuf);
  }

  bufCharCount = INFO_BUFFER_SIZE;
  if (GetUserName(infoBuf, &bufCharCount))
  {
    c_user = TEXT(infoBuf);
  }
}

However while using the TEXT() function, I get the error "LinfoBuf not define". I don't understand this error, plus I declared infoBuf not LinfoBuf. I didn't find the GetUserName function using <windows.h> in MSND documentation but I found GetUserNameA using the header <winbase.h>

Sad1que
  • 37
  • 6

1 Answers1

1

According to the Windows.h header file, TEXT() is not a function, its a macro. Its purpose is to convert string/character literals at compile-time to either wchar_t or char literals, depending on whether the UNICODE conditional is defined or not, respectively.

Basically the definition of TEXT is something like this,

#ifdef UNICODE
#define __TEXT(quote) L##quote

#else
#define __TEXT(quote) quote

#endif
#define TEXT(quote) __TEXT(quote)

In C++, narrow string literals are denoted as "some string" and wide string literals are denoted as L"some string". A ## in a macro, like what we see above, concatenates tokens together. In this case, concatenating L in front of the macro argument when UNICODE is defined. So when we say TEXT("Hello"), the pre-processor output is L"Hello" when UNICODE is defined, otherwise the output is "Hello".

Since infoBuf isn't a string literal, instead its a pointer, when you use TEXT(infoBuf), the compiler resolves it to be LinfoBuf, where the L comes from the macro conversion.

GetComputerName and GetUserName are macro wrappers for the GetComputerNameA/GetComputerNameW and GetUserNameA/GetUserNameW functions, respectively. These functions output the names as char or wchar_t strings. When UNICODE is defined, the W functions are used, otherwise the A functions are used. So, if c_pc and c_user are containers of chars (like std::string), your best option is to use GetComputerNameA and GetUserNameA directly, eg:

#define INFO_BUFFER_SIZE 32767
CHAR   infoBuf[INFO_BUFFER_SIZE];
DWORD  bufCharCount = INFO_BUFFER_SIZE;

Constructor::Contructor(): c_online(true), c_status("Alive"), c_master("Master IP"), c_port(80) 
{

  bufCharCount = INFO_BUFFER_SIZE;
  if (GetComputerNameA(infoBuf, &bufCharCount))
  { 
    c_pc = infoBuf;
  }

  bufCharCount = INFO_BUFFER_SIZE;
  if (GetUserNameA(infoBuf, &bufCharCount))
  {
    c_user = infoBuf;
  }
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
D-RAJ
  • 3,263
  • 2
  • 6
  • 24
  • 1
    Re: "ASCII strings (char*)" -- the macro applies to **string literals**; it doesn't work with a `char*`. A string literal is text enclosed in double quotes. And that's the whole issue: `infoBuf` is some kind of **pointer**, so it's **not** a string literal. `"abcd"` is a string literal, and `L"abcd"` is a wide string literal. Neither one is a pointer. Since a string literal is an array of `char` (or `wchar_t` if it's a wide string literal), in most contexts it **decays** into a pointer to its first element. But it is not a pointer. – Pete Becker Apr 27 '21 at 12:34
  • And note that `std::string`s are **not** "containers of `char*`s". They hold `char` elements, not `char*` elements. – Pete Becker Apr 27 '21 at 12:36
  • @PeteBecker Yup sorry my bad. Got a little confused with the terminology. – D-RAJ Apr 27 '21 at 12:44