Идентификатор (_T) L не определен

#define _T(x)      L ## x
#else /* _UNICODE */
#define _T(x)      x
#endif /* _UNICODE */

#include <Windows.h>
#include <iostream>
#include <TlHelp32.h>
#include <vector>
#include <Psapi.h>
#include <tchar.h>
using namespace std;
DWORD GetModuleBaseAddress(TCHAR* lpszModuleName, DWORD pID) {
    DWORD dwModuleBaseAddress = 0;
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pID); // make snapshot of all modules within process
    MODULEENTRY32 ModuleEntry32 = { 0 };
    ModuleEntry32.dwSize = sizeof(MODULEENTRY32);

    if (Module32First(hSnapshot, &ModuleEntry32)) //store first Module in ModuleEntry32
    {
        do {
            if (_tcscmp(ModuleEntry32.szModule, lpszModuleName) == 0) // if Found Module matches Module we look for -> done!
            {
                dwModuleBaseAddress = (DWORD)ModuleEntry32.modBaseAddr;
                break;
            }
        } while (Module32Next(hSnapshot, &ModuleEntry32)); // go through Module entries in Snapshot and store in ModuleEntry32


    }
    CloseHandle(hSnapshot);
    return dwModuleBaseAddress;
}
int main() {
HWND hWnd = FindWindowA(0, ("Arma 3 \"E:\\SteamLibrary\\steamapps\\common\\asfasf\\asfasfa\" \"-name=Timur Pena\" -mod="));
    if (!hWnd) //If none, display an error
    {
        cout << "Window not found!\n";
        cin.get();
    }

    GetWindowThreadProcessId(hWnd, &pID);
    HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
    if (pHandle == INVALID_HANDLE_VALUE || pHandle == NULL)
    {
        cout << "Failed to open Process!\n";
        cin.get();
        return 0;
    }
    cout << "Process ID:" << pID << "\n";

    const char gameName[] = ("faasfasfagg");
    DWORD gameBaseAddr =GetModuleBaseAddress(_T(gameName), pID);
    cout << gameBaseAddr
}

Вот мой код, хочу найти базовый адресс процесса по имени и id процесса, но VS в строчке

    DWORD gameBaseAddr =GetModuleBaseAddress(_T(gameName), pID); 

пишет идентификатор "Lgamename" не определен. Что делать? К слову я видел как этот же код работает у других людей, пробовал и пастить, то, что было у людей - ошибка все такая же.


Ответы (2 шт):

Автор решения: Georgy Firsov

При сборке программы первым делом в игру вступает препроцессор, который видит строку:

DWORD gameBaseAddr = GetModuleBaseAddress(_T(gameName), pID);

И думает: "Ага! Надо раскрыть макрос, а макрос этот - конкатенация двух токенов", - макрос раскрывается так:

_T(gameName) -> L ## gameName -> LgameName

Напомню: препроцессор работает с токенами (лексемами) и ничего не знает о семантике и значениях.

В итоге выходит так, что указанная строчка компилятору отдается в таком виде:

DWORD gameBaseAddr = GetModuleBaseAddress(LgameName, pID);

Ну а идентификатор LgameName нигде не определен - отсюда и ошибка компиляции.

Если хочется поддерживать и ансишную и юникодную версии, то надо вот так поступить:

const TCHAR gameName[] = _T("faasfasfagg"); // или auto
DWORD gameBaseAddr =GetModuleBaseAddress(gameName, pID);

Но сейчас уже нет смысла поддерживать две версии параллельно - это было актуально давно. Сейчас можно просто поддерживать только юникодную версию:

const wchar_t gameName[] = L"faasfasfagg";
DWORD gameBaseAddr =GetModuleBaseAddress(gameName, pID);

Соответственно и использовать можно юникодные функции:

  • wcscmp вместо _tcscmp
  • FindWindow вместо FindWindowA (ну вообще это макрос, который в юникодном проекте раскроется в FindWindowW)

Поток вывода тоже на wcout поменять можно. Ну и это влечет использование везде wchar_t вместо char или TCHAR.

Для перевода строк между юникодом и анси в рантайме можно использовать MultiByteToWideChar.

К слову, майкрософт вроде определяет макрос _T у себя (если нет, то аналогичный по функционалу TEXT точно есть).

→ Ссылка
Автор решения: Vair

надо просто подключить библиотеку #include <tchar.h>

→ Ссылка